spring事务属性:Spring中的事务传播属性详解

  在使用Spring时大部分会用到他声明式事务简单在配置文件中进行些规则配置利用SpringAOP功能就能轻松搞定事务问题;这里面就涉及到个事务传播属性问题Propagation它在TransactionDefinition接口中定义以供PlatfromTransactionManager使用,PlatfromTransactionManager是spring事务管理核心接口

TransactionDefinition
public erface TransactionDefinition {
  getPropagationBehavior;
  getIsolationLevel;
  getTimeout;
 boolean isReadOnly;
}
  getTimeout思路方法它返回事务必须在多少秒内完成

  isReadOnly,事务是否只读事务管理器能够根据这个返回值进行优化确保事务是只读

  getIsolationLevel思路方法返回事务隔离级别事务管理器根据它来控制另外个事务可以看到本事务内哪些数据

  在TransactionDefinition接口中定义了 5个区别事务隔离级别ISOLATION_DEFAULT 这是个PlatfromTransactionManager默认隔离级别使用数据库默认事务隔离级别.另外 4个和JDBC隔离级别相对应ISOLATION_READ_UNCOMMITTED 这是事务最低隔离级别它充许别外个事务可以看到这个事务未提交数据这种隔离级别会产生脏读不可重复读和幻像读

  在TransactionDefinition接口中共有7种选项可用:

  PROPAGATION_REQUIRED:支持当前事务如果当前没有事务就新建个事务这是最常见选择

  PROPAGATION_SUPPORTS:支持当前事务如果当前没有事务就以非事务方式执行

  PROPAGATION_MANDATORY:支持当前事务如果当前没有事务就抛出异常

  PROPAGATION_REQUIRES_NEW:新建事务如果当前存在事务把当前事务挂起

  PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作如果当前存在事务就把当前事务挂起

  PROPAGATION_NEVER:以非事务方式执行如果当前存在事务则抛出异常

  PROPAGATION_NESTED:支持当前事务新增Savepo和当前事务同步提交或回滚

  现在结合个例子应用以上各种传播属性来进行介绍说明:首先声明两个bean:ServiceA和ServiceB其中ServiceB被引用;

ServiceA {
     void methodA {
       ServiceB.methodB;
     }
  }
  ServiceB {
     void methodB {
     }
  }
  接下来我们就分析下:

  PROPAGATION_REQUIRED

  加入当前正要执行事务不在另外个事务里那么就起个新事务;比如说ServiceB.methodB事务级别定义为PROPAGATION_REQUIRED, 那么由于执行ServiceA.methodA时候 ServiceA.methodA已经起了事务这时ServiceB.methodBServiceB.methodB看到自己已经运行在ServiceA.methodA 事务内部就不再起新事务而假如ServiceA.methodA运行时候发现自己没有在事务中他就会为自己分配个事务 这样在ServiceA.methodA或者在ServiceB.methodB内任何地方出现异常事务都会被回滚即使ServiceB.methodB事务已经被 提交但是ServiceA.methodA在接下来fail要回滚ServiceB.methodB也要回滚

  PROPAGATION_SUPPORTS

  如果当前在事务中即以事务形式运行如果当前不再个事务中那么就以非事务形式运行

  PROPAGATION_MANDATORY

  必须在个事务中运行也就是说他只能被个父事务否则他就要抛出异常

  PROPAGATION_REQUIRES_NEW

  比如我们设计ServiceA.methodA事务级别为PROPAGATION_REQUIREDServiceB.methodB事务级别为PROPAGATION_REQUIRES_NEW 那么当执行到ServiceB.methodB时候ServiceA.methodA所在事务就会挂起ServiceB.methodB会起个新事务等待ServiceB.methodB事务完成以后 他才继续执行他和PROPAGATION_REQUIRED 事务区别在于事务回滚程度了ServiceB.methodB是新起个事务那么就是存在 两个区别事务如果ServiceB.methodB已经提交那么ServiceA.methodA失败回滚ServiceB.methodB是不会回滚如果ServiceB.methodB失败回滚 如果他抛出异常被ServiceA.methodA捕获ServiceA.methodA事务仍然可能提交

  PROPAGATION_NOT_SUPPORTED

  当前不支持事务比如ServiceA.methodA事务级别是PROPAGATION_REQUIRED 而ServiceB.methodB事务级别是PROPAGATION_NOT_SUPPORTED 那么当执行到ServiceB.methodB时ServiceA.methodA事务挂起而他以非事务状态运行完再继续ServiceA.methodA事务 网管联盟bitsCN_com

  PROPAGATION_NEVER

  不能在事务中运行假设ServiceA.methodA事务级别是PROPAGATION_REQUIRED 而ServiceB.methodB事务级别是PROPAGATION_NEVER 那么ServiceB.methodB就要抛出异常了

  PROPAGATION_NESTED

  理解Nested关键是savepo他和PROPAGATION_REQUIRES_NEW区别是PROPAGATION_REQUIRES_NEW另起个事务将会和他父事务相互独立 而Nested事务和他父事务是相依提交是要等和他父事务块提交也就是说如果父事务最后回滚他也要回滚 而Nested事务好处也是他有个savepo:



ServiceA {
    void methodA {      
    try {
        ServiceB.methodB;
      } catch (Exception e) { 
        ServiceC.methodC;
      } 
    } 
  }
  也就是说ServiceB.methodB失败回滚那么ServiceA.methodA会回滚到savepo点上ServiceA.methodA可以选择另外个分支比如 ServiceC.methodC继续执行来尝试完成自己事务;但是这个事务并没有在EJB标准中定义



Tags:  spring事务 spring配置文件详解 spring详解 spring事务属性

延伸阅读

最新评论

发表评论