zoukankan      html  css  js  c++  java
  • spring@Transactional的一点理解

    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:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

    注解@Transactional默认的传播行为是:PROPAGATION.REQUIRED

    若需要设置其他传播行为,设置方法如下:

    @Transactional(propagation = Propagation.REQUIRED)
    public void test() {
        //...
    }
            

    上面的设置的作用是:当方法test出现 “运行时异常” 时,会进行事务回滚(其实是伪回滚,只是把之前的操作改回去。比如有插入操作且是主键是自增长的,假设插入一条记录的操作前,下一id的值是1,但伪回滚后,就变成2了,也就是说,下一次成功插入后,id的值是2而不是1)。

    但是如果,在test方法的方法体中捕获了异常,则不会对事务进行回滚,代码如下:

    @Transactional
    public void test() {
        try{
            //...
        } catch(DataAccessException e) {
            e.printStackTrace();
        }
    }

    上边的代码,如果对多个表进行操作,有成功也有失败的操作,但最后,成功的操作不会被回滚,因为异常被捕获了,spring捕获不到,也就没办法回滚了。

    要想既捕获异常然后做一些操作,又想对失败的操作进行回滚,可以在捕获异常后,再对异常抛出,即让spring能捕获该异常 ,示例如下:

    @Transactional
    public void test() {
        try{
            //...
        } catch(DataAccessException e) {
            e.printStackTrace();
            throw e;
        }
    }

    另外,被@Transactional注解的方法,spring不止对捕获数据访问异常才会进行回滚,而是只要捕获到了运行时异常都会进行回滚,比如下面的示例:

    @Transactional
    public void test() {
        try{
            //...
            int [] counts = new int[]{1};
            int count = counts[1];
        } catch(RuntimeException e) {
            e.printStackTrace();
            throw e;
        }
    }

    上边的代码,会报数组下标越界的“运行时异常” ,但被捕获了,就算之前对数据库的操作是成功的,之前对数据库的操作还是会被回滚。

     暂时到这里,以后遇到新问题再补充。

  • 相关阅读:
    Optimization on content service with local search in cloud of clouds
    译:滑雪租赁问题(ski rental problem)
    计算机专业顶级学术会议
    论文WAN Optimized Replication of Backup Datasets Using Stream-Informed Delta Compression
    FADE:云存储中数据安全删除
    HTML 标签补充
    python mongodb 的调试
    django MultiValueDictKeyError 错误处理
    Using mongo in django to develop web app with python
    使用list和tuple
  • 原文地址:https://www.cnblogs.com/sprinkle/p/6384174.html
Copyright © 2011-2022 走看看