1. 事务特性
原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。
一致性:事务的执行使得数据库从一种正确状态转换成另一种正确状态.
隔离性:在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,
持久性:事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。
2. 数据库的隔离级别
数据库事务的隔离级别有4个, 由低到高依次为Read uncommitted(读未提交) 、Read committed(读已提交) 、Repeatable read(可重复度) 、Serializable(串行化) ,这四个级别可以逐个解决脏读 、不可重复读 、幻读这几类问题。
2.1 什么是脏读, 不可重复读, 幻读?
脏读
一个事务读取到了另一个事务未提交的数据.
- B事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(可能提交也可能回滚)
- 这时,A来读取这条没有提交的数据,并据此做进一步的处理,这就是脏读.
不可重复读
一个事务读取到了另一个事务已提交的数据, 但是前后数据不一致.
- A事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改.
- 则A两次读取的数据不同,我们称之为不可重复读.
幻读
幻读为读到别人已提交的写入(insert)数据库的数据。
幻读与不可重复读的区别为幻读为读到新插入的数据(insert), 而不可重复读主要是读到更改与删除(update、delete).
- A事务先后读取同一条记录,而事务在两次读取之间该数据被插入同等条件的一条数据.
- 则A两次读取的数据条数不同,导致A产生幻影行.这就是幻读.
2.2 数据库4种隔离级别
- 读未提交(read Uncommited):
在该隔离级别,所有的事务都可以读取到别的事务中未提交的数据,会产生脏读问题,在项目中基本不怎么用,安全性太差; - 读已提交(read commited):
这是大多数数据库默认的隔离级别, 但是不是MySQL的默认隔离级别;这个隔离级别满足了简单的隔离要求:一个事务只能看见已经提交事务所做的改变,所以会避免脏读问题;
由于一个事务可以看到别的事务已经提交的数据,于是随之而来产生了不可重复读和幻读等问题. - 可重复读(Repeatable read):
这是MySQL的默认隔离级别,它确保了一个事务中多个实例在并发读取数据的时候会读取到一样的数据;不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。 - 可串行化(serializable):
事物的最高级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争,一般为了提升程序的吞吐量不会采用这个;