事务的特性
- 原子性(A):一个事务的所有操作, 要么全部执行, 要么全部不执行
- 一致性(C):保证数据库从一个正确的状态(满足约束)到另一个正确的状态。
- 隔离性(I):事务并发执行时, 可能会交叉执行, 从而导致不一致的情况发生. 确保事务并发执行时, 每个事务都感觉不到有其他事务在并发的执行。
- 持久性(D):一个事务完成后, 它对数据库的改变应该永久保存在数据库中。
事务并发引发的问题如下:
- 脏读:事务A 读取了 事务B 已经修改但是还没有提交的数据。
- 不可重复读:事务A 读取了数据X; 然后 事务B 修改了数据X 并提交; 然后事务A 再次读取数据X. 对于事务A来说, 两次读取结果不一致. 这种现象就是 不可重复读。
- 幻读:一个事务的两次执行相同的查询, 结果集数目不一致. 幻读 可以 认为是 受 INSERT 和 DELETE 影响 不可重复读 的特例。
- 序列化异常:在可重复读情况下, 可能会出现序列化异常. 比如 X=1 事务A 执行 X++ 操作; 在事务A 提交之前, 事务B 修改 X=10 并提交成功; 由于事务A 是可重复读的, 事务A 看到的数据还是 X=1. 这就发生了序列化异常: 先执行事务A 和 先执行事务B 的结果是不一样的。
事务的隔离级别:
- 读未提交:所有事务都可以看到其他未提交事务的执行结果. 可以看到读未提交允许脏读发生, 脏读是非常危险的, 查询结果非常不可控, 所以读未提交事务隔离级别很少实际应用。
- 读已提交:这是 PostgreSQL 默认的隔离级别, 它满足了一个事务只能看到已提交事务对关联数据所做的改变。
- 可重复读:确保同一个事务在看到的数据内容是一致的。
- 可序列化:最高的隔离级别, 通过强制事务排序, 使之不可能相互冲突, 从而解决幻读问题。