【发布时间】:2013-07-17 18:19:26
【问题描述】:
我对数据库完整性有了相当的了解,并且知道如果我“需要将多个语句作为一个单元执行以使数据保持一致状态”,我应该使用事务。 Database development mistakes made by application developers(第 16 点,选择答案)
Wikipedia 使用示例:
- 从杂货费用帐户中借记 100 美元
- 将 100 美元存入支票账户
如果我尝试记入一个不存在的帐户 ID,并且我正确使用了约束,则会引发异常,我可以捕获它并回滚。如果停电,这两个更改保证是原子的。
但是,如果我理解正确,事务本身不会在所有情况下帮助我:(以 PHP 和 MySQL 为例)
- MySQL:开始事务
- MySQL:从表中选择数据
- PHP:使用所选数据计算状态
- PHP:如果状态有效,插入数据
- PHP:否则,不要插入数据
- MySQL:提交事务
这不起作用,因为查询可以原子地一起执行而不会失败(是 PHP 决定有错误,而不是一些 SQL 约束)。
其次,我刚刚测试过,事务是同步提交的,但可以异步启动。 如果我启动一个事务,并添加 10 秒的延迟,我可以启动慢速脚本,并在这段时间内启动并提交另一个事务,演示并发事务。两个实例可以选择相同的数据,然后才能看到对方的修改。只有修改才能保证是原子的。
那我该怎么办?我想锁定一张桌子是可行的,但这是一种好的做法吗?有些条件可以用 SQL 在一条语句中描述,但更复杂的条件则不能。
【问题讨论】:
标签: sql transactions acid