zoukankan      html  css  js  c++  java
  • Spring 事物传播特性

    Spring 事物传播特性

    这是Spring官方的定义 一共有7种 摘自源码省略了一部分

    public interface TransactionDefinition {
        int PROPAGATION_REQUIRED = 0;
        int PROPAGATION_SUPPORTS = 1;
        int PROPAGATION_MANDATORY = 2;
        int PROPAGATION_REQUIRES_NEW = 3;
        int PROPAGATION_NOT_SUPPORTED = 4;
        int PROPAGATION_NEVER = 5;
        int PROPAGATION_NESTED = 6;
    }
    ROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 
    PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。 
    PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。 
    PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。 
    PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
    PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。 
    PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作

    前面6个都非常好理解,只有 PROPAGATION_NESTED 这个传播特性容易让人搞混淆,所以这里特别说明一下。

    PROPAGATION_REQUIRES_NEW starts a new, independent "inner" transaction for the given scope. This transaction will be committed or rolled back completely independent from the outer transaction, having its own isolation scope, its own set of locks, etc. The outer transaction will get suspended at the beginning of the inner one, and resumed once the inner one has completed. 
    
    Such independent inner transactions are for example used for id generation through manual sequences, where the access to the sequence table should happen in its own transactions, to keep the lock there as short as possible. The goal there is to avoid tying the sequence locks to the (potentially much longer running) outer transaction, with the sequence lock not getting released before completion of the outer transaction. 
    
    PROPAGATION_NESTED on the other hand starts a "nested" transaction, which is a true subtransaction of the existing one. What will happen is that a savepoint will be taken at the start of the nested transaction. íf the nested transaction fails, we will roll back to that savepoint. The nested transaction is part of of the outer transaction, so it will only be committed at the end of of the outer transaction. 
    
    Nested transactions essentially allow to try some execution subpaths as subtransactions: rolling back to the state at the beginning of the failed subpath, continuing with another subpath or with the main execution path there - all within one isolated transaction, and not losing any previous work done within the outer transaction. 
    
    For example, consider parsing a very large input file consisting of account transfer blocks: The entire file should essentially be parsed within one transaction, with one single commit at the end. But if a block fails, its transfers need to be rolled back, writing a failure marker somewhere. You could either start over the entire transaction every time a block fails, remembering which blocks to skip - or you mark each block as a nested transaction, only rolling back that specific set of operations, keeping the previous work of the outer transaction. The latter is of course much more efficient, in particular when a block at the end of the file fails. 

    主要看绿色这段话,大概意思是说 PROPAGATION_NESTED 开始一个 "嵌套的" 事务,  它是已经存在事务的一个真正的子事务. 潜套事务开始执行时,  它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交. 

    说到这大家可能已经清楚这个传播特性是干啥的了,其实就是利用了数据库的还原点的原理,底层还是通过设置Connection.setSavepoint() 与数据库打交道。

        ServiceA {
            /**
             * 事务属性配置为 PROPAGATION_REQUIRED
             */
            void methodA() {
                try {
                    //事务属性配置为 PROPAGATION_NESTED
                    ServiceB.methodB(); //如果methodB()方法出现异常,则回滚方法B的所有SQL操作
                } catch (SomeException) {
                    // 执行其他业务, 如 ServiceC.methodC();
                }
            }
        }

    转载一遍文章讲解的也很详细

    http://www.iteye.com/topic/35907

  • 相关阅读:
    多线程与高并发常见面试题(1)
    LoadRunner 多用户并发 登录,上传数据,登出的脚本教程
    windows cmd 链接远程mysql服务器
    Ubuntu 16.04添加阿里云源
    sqlite 数据库与mysql 数据库使用区别记录
    jdk源码之 hashmap 与hashtable 的区别
    通过构造器启动线程的实现方式及其缺点记录。
    eclipse 中过滤空包,目录树中不显示。
    javascript中正则实现读取当前url中指定参数值方法。
    Reactjs+Webpack+es2015 入门HelloWord(一)
  • 原文地址:https://www.cnblogs.com/daxin/p/3577388.html
Copyright © 2011-2022 走看看