我有一些(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将错误存储在数据库中时,更改将在以后回滚,用户将永远不会看到错误消息。
我可以看到两种简单的解决方案:
messageSystem
。但是,如果我可以像上面那样内联,那么它的可读性和速度都会更快。另外,如果这是可能已经在嵌套事务中的库代码呢?messageSystem
,以便它使用自己的数据库连接。但是,如果我使messageSystem更复杂,并决定它需要在session
表中锁定一个条目,然后才将消息添加到该会话。如果我的主代码由于某种原因也锁定了会话,这可能会导致死锁。所以我的问题是:在内部(可能是嵌套的)事务中有没有办法提交X,这样如果事务被回滚,那么无论如何都会提交X.
或者有任何好方法可以避免我所描述的问题。
谢谢!
答案 0 :(得分:2)
简单的答案是使用第二个数据库连接进行错误记录。