一,数据库事务特性
如果一个数据库说它支持事务,则该数据库必须具备以下四个特性:
1.1,原子性(Atomicity)
原子性是指事务的一系列操作要么全部成功,要么全部失败,不允许存在部分成功部分失败的情形。
1.2,一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,这个主要是一些业务语义的定义。
1.3,隔离性(Isolation)
隔离性是指多个并发执行的事务相互之间的可见性,即一个事务之间的执行要互相隔离,不能互相干扰。希望达到这样的一种状态:对于任意两个并发的事务T1和T2,要么T1执行结束后T2才能开始执行,要么T2执行结束后T1才能开始执行,每个事务都不能感知到对方的存在。
1.4,持久性(Durability)
持久性是指一个事务一旦提交了,那么它对数据库的改变就要是永久的,及时碰到数据库故障,也不能丢失掉提交事务的影响。
二,数据库隔离没有保证导致的问题
2.1,脏读(读取同一个数据)
脏读是指事务T1执行过程中读取了事务T2未提交的数据。比如转账,A给B转账100元,操作如下:
update account set money = money+100 where name="B";
update account set money = money-100 where name = "A";
执行完第一条update语句的时候T2事务来查看B的账户余额,发现多出了100元。而由于某种原因事务T1回滚,此时T2事务读取的数据就是错误的。
2.2,不可重复读(多次读取同一个数据)
不可重复读是指对于数据库中的某个数据,一个事务范围内多次查询该数据返回了不同的值;这是由于在查询期间内,被另一个事务修改并提交了。
例如事务T1在读取某一数据,事务T2立马修改这个数据并提交,事务T1再次读取该数据就得到了不同的结果。
不可重复读和脏读的区别是脏读是读取未提交的数据,不可重复读是读取了已提交的数据。
2.3,幻读(多次读取多个数据)
幻读是事务非独立执行时发生的一种现象。
例如事务T1第一次全表扫描查询总数,此时事务T2立马插入一条数据并提交,事务T1第二次全表扫描查询到的总数就变了。
幻读和不可重复读都是读取了已提交的数据,不同的是不可重复读查询的是同一个单一数据项,该单一数据项被修改了;幻读是查询一批数据,又有新增的数据插入进来。
三,数据库隔离级别
为了解决脏读,不可重复读,幻读各种问题,数据库设置了多种不同的隔离级别,分列如下。
3.1,读未提交(Read uncommitted)
读未提交最弱,两个事务之间不作任何隔离,可以发生脏读,不可重复读,幻读。
3.2,读已提交(Read commited)
读已提交是指事务T2未提交的数据,事务T1不能读取,可以解决脏读的问题。但是不能解决不可重复读和幻读的问题。
3.3,可重复读(Repeatable read)
可重复读是指事务T1在读取过程中,事务T2不能做更新操作,可以解决脏读和不可重复读问题,但是不能解决幻读问题。
3.4,串行化(Serializable)
串行化是最严格的事务隔离级别,即锁全表的方式,任务事务都是互斥的。可以解决脏读,不可重复读,幻读的问题;但是性能也是最差的,一般没有数据库采取这种方式。
在MySQL中默认是可重复读,sql server和Oracle默认是读已提交。