zoukankan      html  css  js  c++  java
  • spring 事务

    spring事务的五个参数来控制管理事务:传播行为、隔离级别、只读提示、超时间隔、回滚规则。

    (1)Spring 事务的传播行为:控制调用方和被调用方的事务边界

    传播行为回答的问题:一个新事务是应该被启动还是被挂起,以及一个方法是否应该在事务的上下文中运行。

    Propagation-required :支持当前事务,如果当前没有事务,则新建一个事务;

    Propagation-supports :支持当前事务,如果当前没有事务,则以非事务方式执行;

    Propagation-mandatory :支持当前事务,如果当前没有事务,则抛出异常;

    Propagation-requires_new :新建事务,如果当前有事务,把当前事务挂起;

    Propagation-not_supported :以非事务方式执行,如果当前有事务,把当前事务挂起;

    Propagation-never :以非事务方式执行,如果当前有事务,则抛出异常。

    PROPAGATION_NESTED:在一个嵌入的事物中执行,否则同PROPAGATION_REQUIRED

    (2)隔离级别:定义一个事务受其他并发事务影响的程度。

    首先了解并发操作可能导致的问题:

    Dirty read -- 脏读,(修改且未提交引起)

    张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。与此同时,事务B正在读取张三的工资,读取到张三的工资为8000。随后,事务A发生异常,而回滚了事务。张三的工资又回滚为5000。最后,事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。

    (大部分数据库缺省的事物隔离级别都不会出现这种状况)

    Norepeatable read --- 不可重复读 ,(修改引起)

    在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。

    与此同时,事务B把张三的工资改为8000,并提交了事务。随后,在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。

    (大部分数据库缺省的事物隔离级别都不会出现这种状况) .

    Phantom read -- 幻读,(添加新记录引起)

    A目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。此时,事务B插入一条工资也为5000的记录。这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。

    (大部分数据库缺省的事物隔离级别都会出现这种状况,此种事物隔离级别将带来表级锁)

    说明 :Oracle数据库缺省的事物隔离级别已经保证了避免脏读和不可重复读。但可能会幻读,避免幻读需要加表级锁,Oracle缺省行级锁。在基于Spring的事物配置中一定要慎重使用ISOLATION_SERIALIZABLE的事物隔离级别。这种配置会使用表级锁,对性能影响巨大。一般没有特殊需要的话,配置为使用数据库缺省的事物隔离级别便可。

    隔离级别:

    Isolation_default:使用数据库默认的隔离级别;

    Isolation_read_uncommitted :允许读未提交的更改,可导致脏读、不可重复读、幻读。

    Isolation_read_committed :保证一个事务提交后的数据才能被另一个事务读取,可避免脏读,不能避免不可重复读、幻读。

    Isolation_repeatable_read:对相同自动的多次读取结果是一致的。可避免脏读、不可重复读,不能避免幻读。

    Isolation_serializable :事务处理为顺序执行。

    (3)只读提示:

    如果一个事务只对后端数据库执行读操作,那么数据库可以利用事务只读特性,采用优化措施。由此可见,只读的优化措施是在一个事务启动时由后端数据库实施的。

    因此只读可能启动一个新事务的的传播行为(required,requires_new,NESTED)有效。

    (4)事务超时

    设置事务执行的最长时间,超时后事务会回滚。

    因为超时时针在事务开始时启动,所以事务超时只对启动一个新事务的的传播行为(required,requires_new,NESTED)有效。

    (5)回滚规则

    定义哪些异常会引起回滚,哪些不会。默认下为:事务只有在出现运行时异常(runtime exception,也就是 unchecked exception)时回滚,而出现受阻异常(checked exception)时不回滚。不够可以在声明事务时设置。

    spring申明式事务配置:1、xml声明事务;2、注释驱动事务

    1、xml声明事务:

    第一步:定义一个事务AOP通知:

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="search*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="check*" propagation="SUPPORTS" read-only="true"/>
            <tx:method name="save*" propagation="REQUIRED"
                rollback-for="cn.com.base.exception.OperationException" />
            <tx:method name="update*" propagation="REQUIRED"
                rollback-for="cn.com.base.exception.OperationException" />                
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="cn.com.base.exception.OperationException" />
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    tx:method 属性包括:isolation ,no_rollbacke_for ,propagation,read_only,rollback_for,timeout

    第二步:定义一个事务切面,即应该在哪些类哪些方法上进行事务切入

    <aop:config>
        <aop:pointcut id="point-service"
            expression="execution(* cn.com.staff.*.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="point-service" />
    </aop:config>

    2、注释驱动事务

    第一步:xml配置文件中增加配置,

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

    <tx:annotation-driven>配置元素告诉spring在类层面或方法层面检查应用程序上下文的所以bean,并且寻找标注了@Transactional的bean,对于标注了@Transactional 的所以bean,<tx-annotation-driven>将自动把事务通知的内容通知给它。这个通知的事务参数将由@Transactional注释的参数来定义

    第二步:@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上

    Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上

    @Service
     @Transactional(rollbackFor=Exception.class)   //对当前类的所有方法起作用
     @SuppressWarnings("serial")
     public class ButtonBo extends GlobalBo {
      ....
      @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) //具体方法上
        public Button findButton(String buttonid) throws BaseException {
         return hibernateEntityDao.get(Button.class, buttonid);
       }
     }
  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/mains/p/3390865.html
Copyright © 2011-2022 走看看