Sprin事务

 spring的事务:
分为编程式事务和申明式事务两种
这里推荐使用申明式事务
申明式事务的实现,有两种:配置文件配置的方式;注解



配置文件方式处理事务:
1.准备事务管理对象;
2.制定事务管理规则
3.指定规则应用的范围;

 事务管理对象 

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
<property name="dataSource" ref="dataSource" ></property>
</bean>


事务管理规则 

isolation : 事务的隔离级别
READ_COMMITTED : 一个事务修改了数据,必须提交之后,其他事务才能拿到这个修改后的数据
READ_UNCOMMITTED : 一个事务修改了数据,提交之前,其他事务就能够拿到这个数据

propagation : 事务的传播行为
REQUIRED : 如果现在有事务,就用现有的;如果没有,就开启新的事务;
REQUIRES_NEW : 不管现在有没有事务,都要开启新的事务;
新的事务开启后,原来如果有事务,就把原来的事务挂起;

rollback-for : 事务回滚的条件
当发生指定的异常的时候,事务就回滚;

no-rollback-for : 事务不回滚的条件
当发生指定异常的时候,不回滚事务

read-only : 是否是只读事务
为true,表示在该事务中,只能读,不能写

timeout : 事务执行需要的时间
事务执行共花费的时间,超过指定的值,不管有没有发生异常,都要回滚

 <tx:advice id="adv" transaction-manager="transactionManager" >
            <tx:attributes>
                <tx:method name="buy*" isolation="READ_COMMITTED" propagation="REQUIRED"  rollback-for="cn.sz.gl.util.StoreHouseLessException,cn.sz.gl.util.MoneyLessException" ></tx:method>
            </tx:attributes>
        </tx:advice> 

绑定规则作用范围

<aop:config>
            <aop:pointcut expression="execution(* cn.sz.gl.service.IBookService.*(..))" id="bs"/>
            <aop:advisor advice-ref="adv" pointcut-ref="bs" />
        </aop:config>

2.

 注解方式实现事务 
准备事务管理对象 

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        <property name="dataSource" ref="dataSource" ></property>
    </bean>

引入事务的注解驱动 

<tx:annotation-driven transaction-manager="transactionManager" /> 

添加注解

@Transactional(isolation=Isolation.READ_COMMITTED,propagation=Propagation.REQUIRED,rollbackFor= {AccountLessException.class,MoneyLessException.class})

事务取值

Propagation (事务的传播属性)
REQUIRED (默认) 业务方法需要在事务中运行,如果方法运行的时候已经开启事务,就加入事务,否则创建新的事务
* NOT_SUPPORTED 声明方法不需要开启事务.如果已经开启事务后调用该方法.则先挂起该事务,方法执行完毕后,事务恢复
* REQUIRES_NEW 不管是否存在事务,都另行开启新的事务.如果先前已经开启事务,挂起原先事务.创建新的事务.
* 新的事务执行结束后,恢复原先事务
* MANDATORY 只能在已经存在的事务中执行,不能自行创建事务,如果在没有开启事务的环境下调用,容器抛出例外
* SUPPORTS 墙头草,有事务就在事务中执行.没事务就在没事务的环境下执行
* NEVER 绝对不能在事务中执行.如果执行.抛出例外
* NESTED 如果有事务存在,开启一个新事务嵌套在上层事务中.开启的新事务具有自己独立的回滚点.新事务的回滚不会对外部事务造成影响,
* 但是外部事务的提交会直接提交嵌套事务
* 如果没有事务存在,则按照REQUIRED属性执行,该属性只对DataSourceTransationManager事务管理器有效


Spring事务的隔离级别(isolation)
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。

什么是脏数据,脏读,不可重复读,幻觉读?
脏读: 指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,
另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一
个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

不可重复读: 指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。
那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据
可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

幻觉读: 指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及
到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,
以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

原文地址:https://www.cnblogs.com/2839888494xw/p/13393676.html