事物并发运行可以造成的问题
1.脏读 读取到另一个事物修改但还未提交的数据
2.不可重复读 同一个事物中多次读取到的数据结果不一致 (比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果)
3.幻读 一个事物读取几行记录后 另一个事物操作了数据 ,在后来的查询中第一个事务就会发现有些原来没有的记录。
(例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样)
事物隔离级别
1、读未提交(READ_UNCOMMITED):允许读取还未提交的改变了的数据。可能导致脏读、幻读、不可重复读。
2、读已提交(READ_COMMITED):允许在并发事务已经提交后读取。可防止脏读,但幻读、不可重复读仍可能发生。
3、可重复读(REPEATABLE_READ):对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏读、不可重复读。但幻读仍可能发生。
4、可串行化(SERIALIZABLE):完全服从ACID的隔离级别,确保不发生脏读、幻读和不可重复读。他在所有的隔离级别中是最慢的,因为要完全锁住在事务中涉及的数据表。
5、Default:使用了后端数据库默认的隔离级别(spring中的选择项,也是isolation属性的默认值,Mysql默认采用REPEATABLE_READ隔离级别,Oracle默认采用READ_COMMITED隔离级别)。
事物传播机制 spring有7总种传播机制
1、PROPAGATION_REQUIRED:支持当前事务,如果当前不存在事务则新建一个。
2、PROPAGATION_SUPPORTS:支持当前事务,如果不存在,就不使用事务。
3、PROPAGATION_MANDATORY:支持当前事务,如果不存在,则抛出异常。
4、PROPAGATION_REQUIRES_NEW:如果当前有事务存在,挂起当前事务,创建一个新的事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前有事务存在,挂起当前事务。
6、PROPAGATION_NEVER:以非事务方式运行,如果当前有事务存在,抛出异常。
7、PROPAGATION_NESTED:如果当前存在一个事务,则该方法运行在一个嵌套的事务中。被嵌套的事务可以从当前事务中单独的提交和回滚。如果当前不存在事务,则开始一个新的事务。各厂商对这种传播行为的支持参差不齐,使用时需注意。
spring隔离级别和事物传播机制配置
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="query*" read-only="true" propagation="SUPPORTS" />
<tx:method name="get*" read-only="true" propagation="SUPPORTS" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
由于没有给method配置isolation属性,所以默认是isolation=‘DEFAULT’,也就是使用后端数据库默认的隔离级别。