失败不能留下半笔转账
如果扣款成功而入账失败,数据库不能把这两步当作一个完整转账留下。原子性要求事务的受保护修改作为整体生效,事务取消时则撤销其已做的相关修改。程序仍可以在内部执行许多读写。
这里的“不可分”描述提交与撤销的结果。它与共享计数器的一次原子读改写属于不同层次;数据库可以通过日志、锁及恢复过程实现一个包含大量指令和磁盘访问的原子事务。
日志支持恢复完整状态
SQLite的回滚日志方案在覆盖数据库页以前保存原内容。若提交尚未完成就中断,恢复过程可以借助日志把数据库还原到事务之前,而不是把写到一半的文件视为有效结果。
具体提交点和恢复手续随日志方案而异。预写日志则先记录修改信息,再按相应规则恢复数据库。判断原子性应看规定的故障场景和恢复结果,不能只看更新函数是否一次返回。
事务保护有明确边界
原子性不单独保证并发事务读到合适的状态,也不代替已提交数据的持久性。隔离和持久化机制仍承担各自的保证,应用也须把应当共同完成的步骤放进正确边界。
部分操作还存在明确例外。PostgreSQL序列计数的变化不会随事务撤销而回退,因此生成编号后取消事务可能留下空号。原子事务不等于系统中每一种计数、日志或外部效果都恢复原样。