繁体   English   中英

在交易期间记录已删除

[英]Record deleted during a transaction

我有一个每秒处理许多查询的系统。 我用mysqlPHP编写我的系统代码。

我的问题是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扩展我使用以下方法处理事务:

然后过程如下:

  1. 使用mysqli::begin_transaction启动新事务
  2. 执行SQL查询
  3. 成功时,使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM