`
TedTian
  • 浏览: 18321 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring中的事务传播的几种方式

阅读更多

Spring中的事务是怎么传播的?

Spring 框架中对TransactionDefinition 接口中的定义 如下:

1.PROPAGATION_REQUIRED
  支持当前的事务,如果当前没有事务,就新建一个

2.PROPAGATION_SUPPORTS
  支持当前事务,如果不存在事务执行非事务方式。对于事务同步的事务管理器来说
  Propagation_Supports 跟一点事务没有的方式是有轻微的区别的。当定义一个事务
  范围时,将会申请同步机制,因此,相同的数据源将共享这个事务范围(取决于事务
  管理器的实际同步配置)

3.PROPAGATION_MANDATORY
  支持当前的事务,如果不存在事务,则抛出异常

4.PROPAGATION_REQUIRES_NEW
  创建一个新的事务,如果当前存在事务,挂起当前的事务
  新创建的事务方法区域外面所有事务管理器的事务都将被挂起,等待当前方法事务的结束。
  这一点特别应用于JtaTransactionManager。

5.PROPAGATION_NOT_SUPPORTED
  执行非事务方式,如果当前存在事务,挂起。
 
6.PROPAGATION_NEVER
  执行非事务方式,如果当前事务存在,抛出一个异常

7.PROPAGATION_NESTED
  如果当前事务存在,在一个嵌套的事务中执行,如果当前没有事务,行为方式跟PROPAGATION_REQUIRED相似
  实际上嵌套事务的创建仅特定事务管理器支持这种方式。(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
  它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)

几点区别:PROPAGATION_REQUIRES_NEW 与 PROPAGATION_NESTED
PROPAGATION_REQUIRES_NEW:在给定的区域中创建一个新的、独立的内部事务。这个事务有他自己的隔离区域和一系列的锁,
他的事务提交或者是回滚将完全独立于外面的事务。在内部事务开始运行之前,外部事务是会被挂起的,直到内部事务执行结束
,外部事务才会恢复。
例如:这种内部独立的事务机制会应用于通过sequences产生记录的ID,这个时候访问sequence表应当发生在一个独立的事务中,
为了使这个Sequence加锁产生序列的时间尽可能的短;这里应当避免将产生序列的方法跟其他逻辑过程放在一个事务中,这样会
导致Sequence表被锁的时间更长,在一个并发量较高的应用中,如果同一时刻在其他的方法中也需要产生序列,那就要等待,刚才
那个事务的释放,所以这个产生序列的方法应该在一个独立的事务中;

PROPAGATION_NESTED:嵌套事务是当前事务一个真实的子事务。当嵌套事务开始时,保存点(savepoint)将形成。如果嵌套事务失败,
将回滚到嵌套事务开始的保存点。嵌套事务又是外面事务的一部分,所以嵌套事务仅当外事务结束时候才会被提交。

这两个事务最大的区别在于PROPAGATION_REQUIRES_NEW是一个全新的事务,完全独立;而PROPAGATION_NESTED是外部事务的子事务
外部事务commit,子事务也会被commit;如果外部事务rollback,子事务也会被rollback;

举个spring事务使用的例子:
由于记账扣款比较频繁,考虑将生成的记账分录批量进行扣款处理;每笔交易有两笔分录(CR与DR);事务配置:PROPAGATION_REQUIRES

扣款的方法如下:
@Transactional
public void updateBalanceByCollection(MemberAccount memberAccount,List<AccountingEntry> entryList) {//同一个账户下面的所有未记账成功的分录
    BigDecimal balance = memberAccount.getBalance();
    for (AccountingEntry accountingEntry : entryList) {
        AccountingDeal accountingDeal =    accountingDealService.findById(accountingEntry.getDealId());
        if(accountingDeal.getStatus().intValue()==0){
                switch (accountingEntry.getChangeType().intValue()) {
                case 1:
                    balance = balance.add(accountingEntry.getChangeAmount());
                    break;
                case 2:
                    balance = balance.subtract(accountingEntry.getChangeAmount());
                    break;
                }
                accountingEntry.setStatus(1);//标记为变更成功
                accountingEntryService.update(accountingEntry);

                //由于事务此处不是立即保存到数据库的,需等到方法执行完毕
                if(accountingEntryService.isUnSuccess(accountingEntry.getDealId(),accountingEntry.getId())){

                    //当另外一条记账分录也扣款成功时,将此笔交易置为成功
                    //deal对应的分录是都已经成功过账则更新deal状态
                    accountingDealService.updateSuccess(accountingEntry.getDealId());
                }
        }
    }
    memberAccountService.updateMemberBalance(balance, memberAccount.getMerchantId(), memberAccount.getAccountCode());//批量更新会员账户余额
}
事务在spring中配置了PROPAGATION_REQUIRES类型  如果在此方法中调用的类中没有事务,沿用当前的事务,如accountingDealService.updateSuccess,accountingEntryService.update均沿用了
当前方法的事务

问题:此方法如果出现异常,将会回滚掉for循环中所有的记录

分享到:
评论

相关推荐

    spring事务几种传播方式

    ### Spring事务传播方式详解 #### 一、引言 在基于Spring框架开发的应用程序中,事务管理是一项重要的功能。为了确保数据的一致性和完整性,合理地配置事务的传播行为至关重要。Spring提供了多种事务传播行为选项...

    事务传播特性了解事务的几种传播特性

    在Java应用开发中,特别是使用Spring框架时,开发者可以通过配置不同的事务传播行为来控制事务如何在方法调用之间传播。这些传播行为对于理解并正确实现业务逻辑至关重要。 #### 二、事务传播特性的种类 根据给定...

    Spring事务的传播特性和隔离级别

    Spring框架提供了多种事务传播特性,用于控制事务在方法调用之间的传播方式。这些传播特性定义了当一个事务方法调用另一个事务方法时的行为: 1. **Propagation_Required**:如果当前存在事务,则继续使用该事务;...

    SPRING事务传播特性&事务隔离级别

    下面详细介绍 Spring 的几种事务传播特性: 1. **PROPAGATION_REQUIRED** - **定义**:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 - **应用场景**:这是最常用的一种事务传播特性...

    Spring事务管理的几种配置方式,

    声明式事务管理是Spring中最常用的事务管理方式,它通过AOP(面向切面编程)来实现。在配置文件中,我们可以通过`&lt;tx:advice&gt;`元素定义事务行为,并使用`&lt;aop:config&gt;`或`@AspectJ`注解来指定哪些方法应该在事务中...

    spring事物的7大传播机制,5个隔离机制

    ### Spring事务的七大传播行为 在深入探讨Spring框架下的事务管理之前,我们首先明确事务的概念。事务是指一组操作作为一个整体,要么全部成功,要么全部失败。Spring提供了多种方式来管理和控制事务,其中一种重要...

    Spring事务五种不同的代理配置

    总的来说,掌握 Spring 事务管理的五种配置方式,有助于我们在开发中更好地控制事务边界,保证数据的一致性和完整性。理解并灵活运用这些知识,能够提升我们的代码质量,降低系统风险,提高系统的稳定性和可靠性。

    spring几种事务配置详解【精】

    本文将深入探讨Spring中的几种事务配置方式,帮助开发者更好地理解和运用。 1. **编程式事务管理** 编程式事务管理是在代码中显式调用事务API来控制事务的开始、提交、回滚等操作。这种方式直接在业务逻辑代码中...

    Spring事务管理Demo

    在Spring事务管理Demo中,通常会包含以下几个步骤: 1. 配置事务管理器:在Spring的XML配置文件中,根据数据库类型(如JDBC、Hibernate、MyBatis等)配置相应的事务管理器。 2. 开启事务:使用`@Transactional`注解...

    spring事务与数据库操作

    ### Spring事务与数据库操作 #### 一、Spring的声明式事务管理 在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。...

    Spring基于XML方式配置事务

    2. **定义事务传播行为**: 事务的传播行为定义了在方法调用时事务应该如何处理。Spring提供了多种传播行为,如`PROPAGATION_REQUIRED`(默认,新事务或加入现有事务)、`PROPAGATION_REQUIRES_NEW`(新建事务,...

    spring声明式事务管理配置方式

    - Spring定义了7种事务传播行为,如PROPAGATION_REQUIRED(默认,如果已有事务则加入,否则新建)、PROPAGATION_REQUIRES_NEW(总是新建事务,即使在已有事务中也如此)等,它们决定了方法调用时事务的处理方式。...

    Spring事务管理失效原因汇总

    描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现问题,暴露了开发者对Spring事务机制不足够了解的问题。标签“Spring 事务 失效”直接概括了本文的知识点范围,即Spring...

    Spring 事务配置的五种方式.docx

    在某些复杂应用中,可能需要结合使用上述几种方式。例如,对于一些核心服务使用注解驱动的事务管理,而对于其他辅助服务则采用编程式事务管理。 在配置事务时,通常需要先定义数据源(DataSource),如使用阿里...

    SpringBoot事务和Spring事务详讲

    Spring 提供了一种抽象化的事务管理方式,使得开发者可以更加专注于业务逻辑而不是底层事务处理的细节。 ##### 1. 核心接口 Spring 的事务管理涉及到几个核心接口,其中最重要的是 `PlatformTransactionManager` ...

    Spring4--3.jdbcTemplate事务

    - **事务传播行为**:定义了如何在嵌套事务中处理事务边界,如REQUIRED(默认,如果已有事务则加入,没有则新建)、REQUIRES_NEW(始终新建一个事务)等。 在实际应用中,通常会结合使用JdbcTemplate和声明式事务...

    spring 事务管理例子(TransactionProxyFactoryBean代理机制 和 tx/aop)

    总结来说,本例子通过`TransactionProxyFactoryBean`和`@Transactional`展示了如何在Spring中实现声明式事务管理,这两种方式都利用了AOP来封装事务逻辑,使代码更加整洁,降低了事务管理的复杂性。在实际应用中,...

    声明式事务控制spring+hibernate集成

    在IT行业中,尤其是在企业级应用开发中,声明式事务控制是一种常见的事务管理方式。它允许开发者通过配置,而不是代码来管理事务,使得事务处理更加简洁、易于维护。本主题聚焦于"声明式事务控制"在Spring 2.5与...

    Spring事务管理配置

    除了`PROPAGATION_REQUIRED`外,Spring还支持其他几种传播行为,包括但不限于: - `PROPAGATION_SUPPORTS`:如果当前存在事务,则支持该事务;如果不存在事务,则以非事务方式执行。 - `PROPAGATION_MANDATORY`:...

Global site tag (gtag.js) - Google Analytics