用mysql命令行可以锁表,但用php代码操作却锁不了表,怎么回事
我先在 mysql 命令行打入以下命令:
begin;
select id,order_amount from member where username=’abc’ for update ;
打入上面两行以后 , 会员表 member 就锁住了,然后我修改 order_amount 的值就无法修改了,
只有再打入命令 commit;
才可以继续读取这个表和修改这个表。
但是我在php文件中这样运行,却没有任何效果,表也无法锁住,请问是什么原因?
php 代码是这样的:
mysql_select_db(“db2”);
mysql_query(“begin”);
$query = “select id,order_amount from member where username=’abc’ for update “;
echo $query;
$result2 = mysql_query($query);
$r5=mysql_fetch_array($result2);
print_r($r5);
因为在php代码中我并没有运行 mysql_query(“commit”); 因为我想看一下用php代码锁表的效果,但是却没有用。
在上面php代码运行以后,还可以用别的php文件继续修改 order_amount 的值。请问是为什么?
回复讨论(解决方案)
事务默认是自动提交的(每条指令后都自动执行 commit)
即便你关闭了自动提交,也会在关闭数据库连接时,自动 commit
锁表的生命周期是当前连接,连接关闭锁就失效了
所以不是
在上面php代码运行以后 而是 在
上面php代码运行时,别的php文件才不可以修改 order_amount 的值。
php执行结束,事务就结束,自动commit了。所以只在你php执行过程中锁。
如果是这样的话,我有两个文件 a.php 和 b.php 都要 对 order_amount 的值进行查询和修改,但我又想用事务控制他们按先后顺序来执行,不要两个同时查询和修改 order_amount 的值,那该如何办呢?
也就是说 a.php 是加积分的,b.php 是减积分的
但这两个文件是同时在不停的运行的,但 a.php 和 b.php 的结果都会影响到 会员积分总数 order_amount 的值
如果不用事务和锁表处理的话,这两个文件同时进行,肯定会把会员积分总数更新得很乱的,这要如何做呢?
我的目的就是加和减要一个个按先后顺序来,那要如何做呢。
你不是加表锁了吗?
那么 a.php 在运行时,b.php 是不能对 order_amount 修改的
注意:这个运行时,是指 a.php 程序正在运行,即浏览器还没有看到结果
按道理应该是这样的,但我用实际运行测试,运行结果却并不是这样
有个会员表 member , 两个字段: username , order_amount 也就是一个是用户名,一个是用户总积分,当前是400积分
另外有一个队列表 memory 有两个字段: username , add_score , 第一个是用户名,第二个是 增加或减少的积分, add_score 的值有正也有负。
现在要做的实验就是 memory 插入 2000条 记录,其中 1000条 add_score 值是正的,另1000条 add_score 是负的,总正负相加为0
然后我用 b.php 处理队列中的数据,每次读出一条记录,更新到会员总积分中,然后删除队列中的这条记录。
a.php 只是查询会员总积分 ,以及 sum 出队列表的数据总和,再输出。 a.php 和 p.php 都在同时运行。
这样的话,如果输出会员的总积分,无论任何时候,都应该是400 的, 因为队列表中的2000条记录积分总数正负相加为0的
但我做测试的时候,却不是这样,是锁表没有生效吗
下面是 b.php 中的代码:
$query = “select * from memory order by id limit 300 “;
$result = mysql_query($query);
while($r2=mysql_fetch_array($result))
{
mysql_query(“begin”);
$query = “select order_amount from member where username=’$r2[username]’ for update “;
$result2 = mysql_query($query);
if($r5=mysql_fetch_array($result2))
{
$new_score = $r5[‘order_amount’] + $r2[‘add_score’] ;
$sql = “update member set order_amount=$new_score’ where t “;
if($rr = mysql_query($sql))
{
$sql66 = “delete from memory where t “;
if($rr66 = mysql_query($sql66))
{
}
} // if $rr
}// if $r5
if( $r5 and $rr and $rr66 ){
mysql_query(“commit”);
}else{
mysql_query(“rollback”);
}
} // while