我可以绕过MySQL中的当前事务吗?

时间:2011-07-20 13:22:48

标签: mysql transactions innodb

我有一些(php)代码在InnoDB表上执行关键更新。

我正在使用(SELECT ... FOR UPDATE),所以我需要进入交易。

当从表单发布数据时正在执行此代码,并且我有一个消息系统,以便将错误/成功消息存储在数据库中,并在下次呈现页面时从数据库中提取。

一些伪代码: (我省略了像try / catch块这样的东西,并在我的真实代码中逃避了)

beginTransaction();

query("SELECT * FROM `table` WHERE id=1 FOR UPDATE");

$x=$_POST[$x];
query("UPDATE `table` SET `field` = $X");

//add other data in the db related to $X
query("INSERT INTO `othertable` (x,y,x) VALUES (......)");


//check for various errors...
$erros=0

if ($error_condition_1) {
    messageSystem("Error Condition 1!")
    $errors+=1;
}
if ($error_condition_2) {
    messageSystem("Error Condition 2!")
    $errors+=1;
}

if ($errors) {
    rollBackTransaction();
} else {
    commitTransaction();
}

问题应该是显而易见的:当messageSystem将错误存储在数据库中时,更改将在以后回滚,用户将永远不会看到错误消息。

我可以看到两种简单的解决方案:

  1. 修改我的代码,以便在事务外调用messageSystem。但是,如果我可以像上面那样内联,那么它的可读性和速度都会更快。另外,如果这是可能已经在嵌套事务中的库代码呢?
  2. 修改messageSystem,以便它使用自己的数据库连接。但是,如果我使messageSystem更复杂,并决定它需要在session表中锁定一个条目,然后才将消息添加到该会话。如果我的主代码由于某种原因也锁定了会话,这可能会导致死锁。
  3. 在交易前检查错误。但实际上我需要通过在之前选择'FOR UPDATE'来锁定相关行。我可以验证输入。
  4. 所以我的问题是:在内部(可能是嵌套的)事务中有没有办法提交X,这样如果事务被回滚,那么无论如何都会提交X.

    或者有任何好方法可以避免我所描述的问题。

    谢谢!

1 个答案:

答案 0 :(得分:2)

简单的答案是使用第二个数据库连接进行错误记录。