[英]Record deleted during a transaction
我有一个每秒处理许多查询的系统。 我用mysql
和PHP
编写我的系统代码。
我的问题是mysqli事务仍然提交事务甚至记录被其他用户同时删除,我的所有表都使用InnoDB
。
这就是我用mysqli编写代码的方法:
mysqli_autocommit($dbc,FALSE);
$all_query_ok=true;
$q="INSERT INTO Transaction() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
$q="INSERT INTO Statement() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
if($all_query_ok==true){
//all success
mysqli_commit($dbc);
}else{
//one of it failed , rollback everything.
mysqli_rollback($dbc);
}
下面是另一个用户在其他脚本中同时执行的查询,然后最终弄乱了预期的系统行为,
$q="DELETE FROM Transaction...";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
请指教,我是否错误地实施了交易? 我读过有关行级锁定的信息,并认为innoDB
会在事务中锁定记录
我不知道你在谈论哪种交易,但是使用mysqli
扩展我使用以下方法处理事务:
然后过程如下:
mysqli::begin_transaction
启动新事务 mysqli::commit
确认步骤2中的查询所做的更改, 或者在步骤2中执行查询时出错,请使用mysqli::rollback
还原它们所做的更改。 您可以将事务视为查询的临时缓存。 它与使用ob_*
函数的PHP中的输出缓存类似。 只要您没有刷新缓存的数据,屏幕上就不会发生任何事情。 与事务相同:只要您没有提交任何内容(并且自动提交已关闭),数据库中就不会发生任何事情。
我做了一些关于行级锁定的研究,它可以锁定删除或更新的记录
更新
在开始事务之后,我必须选择我想锁定的记录,如下所示
SELECT * FROM Transaction WHERE id=1 FOR UPDATE
这样记录将被锁定直到transaction end
。
此方法不适用于MyISAM类型表
看起来像是竞争条件的典型例子。 您可以并行执行两个并发脚本修改数据。 可能您的第一个脚本成功插入记录并提交事务,第二个脚本成功删除后续记录。 我不确定你的意思是“其他用户在其他脚本中同时执行的查询”。
你必须这样做:
mysqli_autocommit($dbc,FALSE);
$dbc->begin_transaction();
$all_query_ok=true;
$q="INSERT INTO Transaction() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
$q="INSERT INTO Statement() VALUES()";
mysqli_query ($dbc,$q)?null:$all_query_ok=false;
if($all_query_ok==true){
//all success
mysqli_commit($dbc);
}else{
//one of it failed , rollback everything.
mysqli_rollback($dbc);
}
调用begin_transaction时我可以使用面向对象或程序样式(我更喜欢面向对象)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.