我的交易应用程序就像这样:
try {
$db->begin();
increaseNumber();
$db->commit();
} catch(Exception $e) {
$db->rollback();
}
然后在increaseNumber()里面我会有一个像这样的查询,这是唯一适用于这个表的函数:
// I use FOR UPDATE so that nobody else can read this table until its been updated
$result = $db->select("SELECT item1
FROM units
WHERE id = '{$id}'
FOR UPDATE");
$result = $db->update("UPDATE units SET item1 = item1 + 1
WHERE id = '{$id}'");
一切都包含在一个事务中但最近我一直在处理一些非常慢的查询,并且我的应用程序中出现了很多并发性,所以我无法确保查询以特定的顺序运行
死锁会导致ACID交易中断吗?我有一个函数添加一些东西,然后另一个删除它,但是当我有死锁时,我发现数据完全不同步,就像事务被忽略一样。
这是否会发生或其他问题?
谢谢,Dominic
答案 0 :(得分:2)
好吧,如果一个事务遇到一个没有释放的锁(来自另一个事务),它将在超时后失败。我相信默认值是30秒。如果有人在数据库上使用任何第三方应用程序,您应该记下。我知道一个事实,例如, SQL Manager 2007 不会在InnoDB上发布锁,除非您与数据库断开连接(有时它只需要一个提交事务...好吧,一切),这会导致很多查询在超时后失败。当然,如果您的交易符合ACID,它应该全有或全无。只有在事务之间中断数据时它才会中断。
您可以尝试延长超时,但30秒锁可能意味着更深层次的问题。当然,这取决于您使用的存储引擎(MySQL
标记和我假设InnoDB的交易。)
您还可以尝试启用query profiling,查看是否有任何查询运行了一段荒谬的时间。请注意,它确实会降低性能,因此它可能不是生产解决方案。
答案 1 :(得分:1)
ACID中的A代表Atomic,因此没有死锁不能使ACID事务中断 - 相反它会使它不会发生在全有或全无。
更有可能的是,如果您的数据不一致,那么您的应用程序在逻辑单个事务中执行多个“事务”,例如:用户创建和帐户(transaction-begin ..- commit),用户设置密码(事务 - 开始......-死锁..-回滚)你的应用程序忽略了错误并继续,现在你的数据库留下了用户创建的密码。
在应用程序中查看除了回滚之外应用程序正在做什么,以及逻辑上是否有多个部分来构建一致数据。