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