PROPAGATION_REQUIRES_NEW事务管理中的变量

本文详细探讨了Spring框架中PROPAGATION_REQUIRED与PROPAGATION_REQUIRES_NEW两种事务传播级别的具体实现方式及其内部机制。通过具体的Java示例代码,展示了这两种事务传播级别下,如何创建独立的数据库连接以及它们之间的交互过程。
PROPAGATION_REQUIRES_NEW传播方式对于第二个事务,会产生一个全新的Connection来处理.两个连接的操作类似于:
[Java] view plain copy
  1. Connection con1 = ds.getConnection();  
  2. con1.setAutoCommit(false );  
  3. con1.executeUpdate(sql1);  
  4. con1.executeUpdate(sql2);  
  5. ...  
  6. Connection con2 = ds.getConnection();  
  7. con2.setAutoCommit(false );  
  8. con2.executeUpdate(sql1);  
  9. con2.exeucteUpdate(sql2);  
  10. ...  
  11. con2.commit();  
  12. con2.setAutoCommit(true );  
  13. con2.close();  
  14.   
  15. con1.executeUpdate(sqln);  
  16. ...  
  17. con1.commit();  
  18. con1.setAutoCommit(false );  
  19. con1.close();<pre></pre>  

Spring事务管理中事务涉及的变量主要有:

变量在两事务(第一个事务为PROPAGATION_REQUIRED,第二个事务为PROPAGATION_REQUIRES_NEW)创建、执行、完成过程中的变化如下:

 

第一个事务       
 TransStatus1  Transaction1  ConnectionHolder1 
 TransactionTransaction1 ConnectionHolderConnectionHolder1 SynchronizedWithTransactionTRUE
 newTransactionTRUE   Connectioncon1
 newSynchronizationTRUE resource   
 suspendedResourcesnull keydataSource Synchronizations 
 savepointnull valueConnectionHolder1 ArrayList1empty
         
第二个事务:doGetTransaction
Transaction2 
ConnectionHolderConnectionHolder1
         
doSuspendTransaction    
 Transaction2  SuspendedResourcesHolder1 
 ConnectionHoldernull suspendedSynchronizationsArrayList1
   suspendedResourcesConnectionHolder1
 resource   
 null  Synchronizations 
    null 
         
doBegin
TransStatus2 Transaction2 ConnectionHolder2 
TransactionTransaction2ConnectionHolderConnectionHolder2SynchronizedWithTransactionTRUE
newTransactionTRUEConnectioncon2
newSynchronizationTRUEresource 
suspendedResourcesSuspendedResourcesHolder1keydataSourceSynchronizations 
 valueConnectionHolder2ArrayList2empty
savepoinenull
         
triggerBeforeCommittriggerBeforeCompletiondoCommit:con2.committriggerAfterCompletion 
doCleanupAfterCompletion
con2恢复autoCommit与isolationLevelresource Synchronizations 
关闭连接null null 
         
resume    
已经恢复到第一个事务doBegin刚完成状态 resource  Synchronizations 
 keydataSource ArrayList1empty
 valueConnectionHolder1  
         

源码:

[Java] view plain copy
  1. public   void  addEmployee(Employee employee)  throws  SQLException {  
  2.   transactionTemplate.execute(new  TransactionCallback() {  
  3.     public  Object doInTransaction(TransactionStatus ts) {  
  4.       try  {  
  5.         jdbcTemplate.update("INSERT INTO Employee (username,age) VALUES(?, ?)" ,   
  6.           new  Object[]{ "lizi" , new  Integer( 22 )});  
  7.         departmentDao.addDepartment();  
  8.         jdbcTemplate.update("INSERT INTO Employee (username,age) VALUES(?, ?)" ,   
  9.           new  Object[]{ "lijun" , new  Integer( 55 )});  
  10.         System.out.println("更新成功" );  
  11.   
  12.       } catch  (Exception ex) {  
  13.         ex.printStackTrace();  
  14.         System.out.println("更新失败" );  
  15.         ts.setRollbackOnly();  
  16.       }  
  17.       //ts.setRollbackOnly();   
  18.       return   null ;  
  19.     }  
  20.   });  
  21. }  
[Java] view plain copy
  1. //DepartmentDao.java   
  2. public   void  setTransactionTemplate(  
  3.     TransactionTemplate deptTransactionTemplate) {  
  4.   this .transactionTemplate = deptTransactionTemplate;  
  5.   deptTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);  
  6.     
  7.   DataSourceTransactionManager manager = (DataSourceTransactionManager)deptTransactionTemplate.getTransactionManager();  
  8.   DataSource ds = manager.getDataSource();  
  9.     
  10.   jdbcTemplate = new  JdbcTemplate(ds);  
  11. }  
  12.   
  13. public   void  addDepartment() {  
  14.   transactionTemplate.execute(new  TransactionCallback() {  
  15.   
  16.     public  Object doInTransaction(TransactionStatus status) {  
  17.       try  {  
  18.         jdbcTemplate.update("insert into department (dept,deptName) values('IT','IT department')" );  
  19.       } catch  (Exception ex) {  
  20.         ex.printStackTrace();  
  21.         status.setRollbackOnly();  
  22.       }  
  23.       return   null ;  
  24.     }  
  25.       
  26.   });  
<think>首先,用户的问题是:“我想了解声明式事务的传播级别 请问声明式事务的传播级别有哪些”。我需要根据系统级指令来回答。 系统级指令: 1. 所有行内数学表达式必须使用$...$格式。 2. 独立公式必须使用$$...$$格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识,例如:[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:用户提供了几个引用,我需要参考这些引用,但用户说“上述引用仅供参考,并不是用户真正的需求”,所以我应该基于用户的问题来回答,而不是完全依赖引用。 用户的问题是关于声明式事务的传播级别。从引用中,我可以提取相关信息: - 引用[3]详细列出了Spring的7种传播行为。 - 引用[4]也提到了传播行为。 - 其他引用涉及隔离级别等,但用户问的是传播级别,所以聚焦于此。 传播级别(传播行为)在Spring事务管理中定义。常见的有: - PROPAGATION_REQUIRED - PROPAGATION_SUPPORTS - PROPAGATION_MANDATORY - PROPAGATION_REQUIRES_NEW - PROPAGATION_NOT_SUPPORTED - PROPAGATION_NEVER - PROPAGATION_NESTED 我需要列出这些并简要解释。 回答结构: 1. 开头直接回答问题。 2. 列出传播级别及其含义。 3. 使用引用标识来引用来源。 4. 最后生成相关问题。 由于用户提供了引用,我应该自然地添加引用标识。例如,在解释传播行为时,引用[^3]或[^4]。 数学表达式:用户的问题是关于事务传播的,可能不涉及数学表达式。但如果有变量或公式,需要使用LaTeX。在这个上下文中,可能不需要数学表达式,除非有特定公式。但为了遵守指令,如果有机会,可以适当添加。例如,在解释概念时,如果有数学部分,但我认为这里主要是文本描述。 确保LaTeX语法正确:如果没有数学部分,就不需要添加。 生成相关问题:在回答结束后,添加“§§相关问题§§”部分,列出3-5个相关问题。 完整回答结构: - 先回答用户问题。 - 然后添加相关问题。 现在,提取传播级别的信息: 从引用[3]: - PROPAGATION_MANDATORY:必须运行在事务中,否则异常。 - PROPAGATION_NESTED:嵌套事务。 - PROPAGATION_NEVER:不应该在事务中运行,否则异常。 - PROPAGATION_NOT_SUPPORTED:不应该在事务中运行,挂起现有事务。 - PROPAGATION_SUPPORTS:支持事务,但不需要。 - PROPAGATION_REQUIRES_NEW:必须在新事务中运行。 - PROPAGATION_REQUIRES:必须在事务中运行。 引用[4]也类似。 我将基于这些描述。 回答内容: - 介绍声明式事务的传播级别。 - 列出7种传播行为及其含义。 - 添加引用标识。 最后,生成相关问题,例如: 1. 传播级别如何影响事务管理? 2. 在实际应用中,如何选择传播级别? 3. 传播级别与隔离级别有什么区别? 4. 等等。 确保语言为中文。</think>### 声明式事务的传播级别介绍 在Spring框架中,声明式事务的传播级别(也称为传播行为)定义了事务方法如何与现有事务交互。传播级别是事务管理的关键属性,它决定了当一个事务方法被调用时,是否启动新事务、加入现有事务或挂起事务。Spring定义了7种标准传播级别,这些级别基于事务的上下文环境(如是否有活动事务)。下面我将逐一列出并解释这些传播级别,确保回答清晰可靠。信息主要参考自Spring官方文档和相关实践[^3][^4]。 #### 声明式事务的传播级别列表 1. **PROPAGATION_REQUIRED**: - 含义:如果当前存在活动事务,则加入该事务;如果没有活动事务,则启动一个新事务。 - 适用场景:适用于大多数业务方法,确保操作在事务中执行,例如数据库更新操作[^3][^4]。 2. **PROPAGATION_SUPPORTS**: - 含义:如果当前存在活动事务,则加入该事务;如果没有活动事务,则以非事务方式执行。 - 适用场景:适用于只读查询方法,可以优化性能,但不会强制事务边界[^3][^4]。 3. **PROPAGATION_MANDATORY**: - 含义:强制要求当前必须存在活动事务,否则抛出异常。如果存在事务,则加入。 - 适用场景:用于确保方法不被意外调用在非事务环境中,例如关键业务逻辑[^3][^4]。 4. **PROPAGATION_REQUIRES_NEW**: - 含义:无论当前是否存在活动事务,都启动一个新事务。如果存在活动事务,则将其挂起;新事务完成后恢复原事务。 - 适用场景:适用于独立操作(如日志记录),需要避免与主事务冲突[^3][^4]。 5. **PROPAGATION_NOT_SUPPORTED**: - 含义:以非事务方式执行。如果当前存在活动事务,则将其挂起;方法执行完毕后恢复原事务。 - 适用场景:用于不需要事务支持的方法(如纯计算操作),减少资源开销[^3][^4]。 6. **PROPAGATION_NEVER**: - 含义:强制要求当前不能存在活动事务,否则抛出异常。方法始终以非事务方式执行。 - 适用场景:确保方法在无事务环境中运行,防止事务污染[^3][^4]。 7. **PROPAGATION_NESTED**: - 含义:如果当前存在活动事务,则在嵌套事务中执行(嵌套事务可独立提交或回滚,不影响封装事务);如果没有活动事务,则行为等同于PROPAGATION_REQUIRED。 - 适用场景:适用于部分可回滚的子操作(如批量处理中的子任务),提供更细粒度控制[^3][^4]。 #### 关键说明 - **为什么传播级别重要?**:传播级别帮助管理事务边界,避免脏读、不可重复读等问题。它与事务隔离级别(如READ_COMMITTED)配合使用,确保数据一致性[^4][^5]。 - **如何设置传播级别?**:在声明式事务中,可以通过`@Transactional`注解的`propagation`属性配置,例如: ```java @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateOrder() { // 业务逻辑 } ``` - **最佳实践**:选择传播级别时,需考虑方法语义。例如,PROPAGATION_REQUIRED适合核心业务方法,而PROPAGATION_SUPPORTS适合查询方法[^3][^4]。传播级别的错误配置可能导致事务回滚或性能问题。 通过理解这些传播级别,您可以更灵活地设计事务性应用。如果您有具体场景,我可以提供更针对性的建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值