一、事务的四个特性 事务包括四个特征(ACID) 1、原子性(Atomicity):也就是说事务中的操作必须要保证是原子性的,不可再分的,意思就是说,一步失败,则全部失败,全部成功,才算成功。 2、一致性(Consistency):事务一旦完成,则必须保证,事务内的业务是一致的,不可能出现一部分成功的情况。现实中,数据也应该不被破坏。 3、隔离性(Isolation):事务通常来说,同时开启多个,需要保证各个事务之间不互相干扰,防止数据破坏。 4、持久性(Durability):事务一旦完成,无论系统出现什么情况,其结果不受影响。
二、事务的基本属性。 事务的属性包括一下几点。 Spring中的事务管理器接口TransactionDefinition,源码如下:
public interface TransactionDefinition { int getPropagationBehavior(); // 返回事务的传播行为 int getIsolationLevel(); // 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据 int getTimeout(); // 返回事务必须在多少秒内完成 boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的 }下面来着重讲解一下其中的几点重要属性 1、传播行为(propagation behavior) 事务的传播行为有以下7种:
2、隔离级别 隔离级别定义了一个事务可能受其他并发事务影响的程度。 首先来看一下,事务并发情况下可以出现的问题 1)脏读:事务T1修改了a数据,但还未提交,此时,事务T2读取到了a数据,但是如果T1回滚,则T2读取到的数据为脏数据。 2)不可重复读:事务T1重复读取数据a的值,得到不同的值,这是由于T1在读取数据的同时,事务T2对数据a进行了修改。 3)幻读:幻读与不可重复读类似,事务T1查询某些数据多次,得到不同数量的数据,这是由于事务T2在T1操作的同时,新增或者删除了某些数据,造成了改结果。
★ 不可重复读和幻读的区别 1)不可重复读注重的是修改: 事务T1读取第一次:a=100; 事务T2修改:a=200; 事务T2读取第二次:a=200; 造成不可重复读。
幻读注重的是新增或者删除。 事务T1查询第一次满足条件m的数据有:100条; 事务T2新增数据,且满足条件m:10条; 事务T1查询第二次满足条件m的数据有:110条; 这就造成了幻读。
2)不可重复读只需要锁住满足条件的记录; 幻读要锁住满足条件及其相近的记录。
再来说说隔离级别
3、只读 事务的第三个特性是它是否为只读事务。如果事务只对后端的数据库进行该操作,数据库可以利用事务的只读特性来进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让它应用它认为合适的优化措施。
4、事务超时 为了使应用程序很好地运行,事务不能运行太长的时间。因为事务可能涉及对后端数据库的锁定,所以长时间的事务会不必要的占用数据库资源。事务超时就是事务的一个定时器,在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。
5、回滚规则 事务五边形的最后一个方面是一组规则,这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的) 但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。