数据库事务
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。一个事务的执行过程包括执行操作,和提交操作。
事务存在的目的,是为了满足一下2个目的:
-
为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
-
当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
ACID
为保证事务(transaction)是正确可靠的,事务必须具备ACID这四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。
-
原子性(atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
-
一致性(consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
-
隔离性(isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
-
持久性(durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
事务隔离
其中原子性,一致性,持久性,满足了单个事务执行的情况下,数据库最基本的数据一致。
隔离性则保证了多个事务并行执行时,事务间不互相影响。事务并发的影响�有如下三种
- 脏读(dirty reads)
当一个事务允许读取另外一个事务修改但未提交的数据时,就可能发生脏读。
- 不可重复读
在一次事务中,当一行数据获取两遍得到不同的结果表示发生了“不可重复读”。
- 幻读
在事务执行过程中,当两个完全相同的查询语句执行得到不同的结果集。这种现象称为“幻影读(phantom read)”。
事务隔离级别
很多数据库管理系统定义了不同的“事务隔离等级”来控制锁的程度。在很多数据库系统中,多数的数据库事务都避免高等级的隔离等级(如可序列化)从而减少对系统的锁定开销。程序员需要小心的分析数据库访问部分的代码来保证隔离级别的降低不会造成难以发现的代码bug。相反的,更高的隔离级别会增加死锁发生的几率,同样需要编程过程中去避免。
为了平衡并行执行的性能和并行执行时的数据�一致性,事务隔离根据影响的情况,分成了不同的几个级别。
- 读未提交(Read uncommitted)
最低的隔离级别。允许“脏读”(dirty reads),事务可以看到其他事务“尚未提交”的修改。
- 读提交(read committed)
基于锁机制并发控制的DBMS需要对选定对象的写锁一直保持到事务结束,但是读锁在SELECT操作完成后马上释放(因此“不可重复读”现象可能会发生)。和前一种隔离级别一样,也不要求“范围锁”。
- 可重复读(repeatable read)
基于锁机制并发控制的DBMS需要对选定对象的读锁(read locks)和写锁(write locks)一直保持到事务结束,但不要求“范围锁”,因此可能会发生“幻影读”。
- 串行化(Serializable)
最高的隔离级别。在基于锁机制并发控制的DBMS实现可序列化,要求在选定对象上的读锁和写锁保持直到事务结束后才能释放。在SELECT 的查询中使用一个“WHERE”子句来描述一个范围时应该获得一个“范围锁”(range-locks)。这种机制可以避免“幻影读”(phantom reads)现象。
通过一下的表格,归纳了不同的隔离级别,可能会遇到的读取现象
隔离级别vs读现象
隔离级别 | 脏读 | 不可重复读 | 幻影读 |
---|---|---|---|
未提交读 | 可能发生 | 可能发生 | 可能发生 |
提交读 | - | 可能发生 | 可能发生 |
可重复读 | - | - | 可能发生 |
可序列化 | - | - | - |
�锁的控制和隔离级别的关系。
隔离级别vs 锁持续时间
在基于锁的并发控制中,隔离级别决定了锁的持有时间。"C"-表示锁会持续到事务提交。 "S" –表示锁持续到当前语句执行完毕。如果锁在语句执行完毕就释放则另外一个事务就可以在这个事务提交前修改锁定的数据,从而造成混乱。
隔离级别 | 写操作 | 读操作 | 范围操作 (...where...) |
---|---|---|---|
未提交读 | S | S | S |
提交读 | C | S | S |
可重复读 | C | C | S |
可序列化 | C | C | C |
网友评论