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);
       }
     }
  • 相关阅读:
    mybatis批量处理sql
    jdbc连接数据库使用sid和service_name的区别
    js 监听浏览器刷新还是关闭事件
    websocket
    hutool java工具架包功能介绍
    SpringMvc+ajax 实现json格式数据传递
    springMVC form表单提交多个对象集合--使用ajax提交--前台json格式数据封装方法
    linux C之判断文件或目录是否存在 access函数
    Linux C -> symlink 和 readlink -> 符号链接
    linux c开发: 在程序退出时进行处理
  • 原文地址:https://www.cnblogs.com/mains/p/3390865.html
Copyright © 2011-2022 走看看