一、概念
数据库事务是指作为单个逻辑工作单元执行的一系列操作。
二、基本属性(ACID)
原子性:一个事务是一个不可分割的工作单位,事务中的操作要么都做 ,要么都不做。
一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。
隔离性:一个事务的执行不能被其他事务干扰。
持久性:事务一旦提交,它对数据库中数据的改变应该是永久性的。
三、可能存在的问题
更新丢失:两个事务A,B同时更新一行数据data1,但是事务B却中途失败退出,导致对数据data1的两个修改都失效了。
脏数据读取:一个事务A读取了某行数据data1,但是另一个事务B已经更新了此数据data1,但还没有能够及时提交。当事务B发生了回滚操作,数据data1就是非法的数据,即脏数据。
不可重复读:一个事务A读进一条记录Record1,另一个事务B更改了这条记录并提交完毕,这时事务A再次读取记录Record1时,发现它已经改变了。
幻读:一个事务A用where子句检索一个表T1的数据,另一个事务B插入一条新的记录Record1,并且Record1符合where条件,这样当事务A再次用相同的where条件检索数据时,就会多出一条原本不属于T1中的记录Record1。
四、事务隔离机制
未授权读取:假设A事务即不发布共享锁,也不接受独占锁,那么并发的B或者其它事务可以改写A事务读取的数据,那么并发的C事务读取到的数据的状态和A的或者B的数据都可能不一致,那么。脏读、不可重复读、幻象数据都可能存在。
授权读取:假设A事务对正在读取数据Data放置了共享锁,那么Data不能被其它事务改写,所以当B事务对Data进行读取时总和A读取的Data数据是一致的,所以避免了脏读。由于在A没有提交之前可以对Data进行改写,那么B读取到的某个值可能会在其读取后被A更改从而导致了该值不能被重复取得;或者当B再次用相同的where字句时得到了和前一次不一样数据的结果集,也就是幻像数据。
可重复读取:假设A事务对读取的所有数据Data放置了锁,以阻止其它事务对Data的更改,在A没有提交之前,新的并发事务读取到的数据如果存在于Data中,那么该数据的状态和A事务中的数据是一致的,从而避免了不可重复的读取。但在A事务没有结束之前,B事务可以插入新记录到Data所在的表中,那么其它事务再次用相同的where字句查询时,得到的结果数可能上一次的不一致,也就是幻像数据。
序列化:提供严格的事务隔离。要求事务序列化执行,事务只能一个接一个地执行,但不能并发执行。
四、事务隔离级别和可能问题对照表
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
未授权读取(Read uncommitted) | 可能 | 可能 | 可能 |
授权读取(Read committed) | 不可能 | 可能 | 可能 |
可重复读(Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化(Serializable) | 不可能 | 不可能 | 不可能 |
五、乐观锁与悲观锁
悲观锁,是悲观地认为自己在读取数据的时候别人也在对数据进行读写,所以在自己读写数据的时候对数据进行锁定,知道自己操作完毕。悲观锁的代表软件是VSS。
乐观锁,认为在自己对数据进行读写的时候不会有其他人对数据进行读写,所以不进行数据库机制的限制版本的限制。乐观锁的代表软件是CVS。