数据库事务管理小议
事务的概念
事务(Transaction)是并发控制的基本单位,是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。事务的提出主要是为了解决并发情况下保持数据一致性的问题。 要支持事务的操作,那么必须要具备以下四个特性:
-
Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
-
Consistency(一致性):事务执行前后数据都必须处于一致状态。只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
-
Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。并行事务之间相互独立。
-
Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。
事务隔离
多个并发事务同时访问数据库,可能存在问题:
更新丢失
两个事务同时更新一行数据,事务A对数据的更新把事务B的数据更新覆盖了。
脏读
事务A读取到了事务B尚未提交的数据操作结果,而这些操作是可以回滚的。
不可重复读
一个事务对同一行数据读取多次,却得到了不同的结果:
-
虚读:事务A读取某一数据后,事务B对其作了修改,当事务A再次读取时得到了与上一次不同的数据
-
幻读:事务在操作过程中进行了两次查询,第二次查询的结果包含了第一次未出现的数据或者缺少了第一次查询的数据
为了保证数据并发读取的正确性,提出了事务隔离级别:
Read Uncommitted,未授权读取
也称为读未提交:允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
Read Committed,授权读取
也称为读提交:可避免脏读取,但无法避免不可重复读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
Repeatable Read,可重复读取
可避免不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
Serializable,序列化
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。MySQL默认是Repeatable Read,Oracle、SQL Server是Read Committed。