1、事务的四个要素和特性:
数据库事务正确执行的四个基本要素:ACID,也即原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)。
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。(不鸣则已,一鸣惊人,很强的原则性,有板有眼,不模棱两可)
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。(两个银行账户之间相互转账,不考虑与其它任何账户之间的交易,则转账前后,两个账户的总金额是一样的,前后是一致状态)
隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。(天下攘攘,为我独尊;事务很多,就我一个)
持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。(覆水难收,不可挽回)
2、事务不考虑隔离性会带来的问题
(1)脏读: 是指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。(被放鸽子了,读了个子虚乌有的假数据,)
(2)不可重复读 :是指在数据库访问时,一个事务范围内的两次相同查询却返回了不同数据。在一个事务内多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改,第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(仿佛看花了眼,明明读的是同一个数据,但是前后两次读取的值不一样)
(3)幻读: 是指当事务不是独立执行时发生的一种现象,比如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么就会发生,操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。 (仿佛产生了幻觉,前后两次读取数据的数据量竟然不一样,第一次获取列表读了12条数据,第二次竟然读了17条数据,冒出来5条数据)
不可重复读和幻读区别:
不可重复读重点在于update(更新导致同一个数据前后读取的值不一样),而幻读的重点在于insert(插入数据导致前后读取的数据记录数有变化)。
3、数据库中的事务隔离级别
- READ_UNCOMMITTED(读未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
- READ_COMMITTED(读已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。Oracle 默认采用的隔离级别是读已提交。
- REPEATABLE_READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。MySQL默认的隔离级别是可重复读。
- SERIALIZABLE(串行读): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。