有没有办法提交部分交易?

时间:2014-08-19 09:50:31

标签: mysql sql transactions

有一个函数A,它启动一个事务,做一些工作,然后调用函数B,做更多工作,并提交事务。 A还会捕获任何异常,这会触发回滚而不是提交。

我的问题是,如果B遇到错误,我想将该错误记录到我的数据库中,然后阻止A中的事务提交。有没有办法做到这一点?我不能只进行B调用回滚,因为B可能被除A以外的其他函数使用,这可能会以不同的方式处理异常。所以B仍然需要抛出异常,从而触发回滚。但是,这会清除我刚刚创建的数据库日志条目。那么,有没有办法让一个函数在事务中间提交一个插入,同时允许事务的其余部分回滚?

供参考:我在PHP中使用Eloquent ORM在带有InnoDB表的MySQL数据库上执行此操作。我没有直接使用原始SQL命令的任何问题,但我不想切换到不同的表类型。

3 个答案:

答案 0 :(得分:1)

如果要跟踪任何特定错误,可以使用handlers。但我不认为只提交交易的一部分是个好主意。

您还可以查看signal

答案 1 :(得分:1)

您可以将日志发送到MyISAM表格(自MyISAM tables do not support transactionsCOMMITROLLBACK以来,这些内容对他们没有任何影响)。

[编辑]
...但我刚刚注意到你写的部分:“我不想切换到不同的表类型”。 As 3m1n4 suggests,无法提交事务 * 任意部分。我能想到的唯一解决方法是从不同的事务中填充日志表。

* 可以通过save points部分回滚交易,但我不认为这与您的问题相关

答案 2 :(得分:-1)

关系数据库的第一个原则之一是ACID(原子性,一致性,隔离性,耐久性)。 我认为原子性解释了很多你在问什么。原子性确保交易总是全有或全无。这意味着如果事务的一部分失败,整个事务将被回滚,并且DB保持不变状态。

INSERT,UPDATE和DELETE是Autocomitted的状态,但如果将它们作为事务的一部分,则可以覆盖此行为。在mySql中,它是START TRANSACTION语句,最后提交整个Transaction。 有关详细说明,请参阅此链接:

http://dev.mysql.com/doc/refman/5.6/en/commit.html

也是一个非常好的Q和A: https://dba.stackexchange.com/questions/4252/do-inserts-get-auto-committed