不久前,为了避免事务的嵌套,刻意去修改以前的设计,导致各部分之间经常出现职责的混淆和重复,颇为头痛.今天在一篇名为《解惑 spring 嵌套事务》文章中找到了答案.
原因出在没有能够深刻理解事务声明中不同事务传播属性配置的的含义.原来想象是这样的(见下面示例代码),serviceA和ServiceB的所有方法都被配置声明事务,当serviceA的方法调用ServiceB的方法,我便"顺理成章"的认为methodA和methodB都各自有自己的事务,这会带来两个问题:1)性能下降;2)methodB事务提交后,methodA因异常而回滚,methodB去无法回滚.
ServiceA {
/**
* 事务属性配置为 PROPAGATION_REQUIRED
*/
void methodA() {
ServiceB.methodB();
}
}
ServiceB {
/**
* 事务属性配置为 PROPAGATION_REQUIRES_NEW
*/
void methodB() {
}
}
如果理解了事务传播属性的含义就不会出现这样的误解.见下方解释:
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。 它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager) |
其实若事务传播属性配置为PROPAGATION_REQUIRED,上例中的问题根本不会出现.因为根据上方的解释,当methodB执行的时候,当前线程已经开始了一个事务,所以methodB是不会产生新的事务,也就意味着随之而来的两个问题是不存在的.除非对methodB使用了PROPAGATION_REQUIRES_NEW的配置,才会使得methodB有自己的事务.
关于PROPAGATION_NESTED所指的嵌套,还请参见《解惑 spring 嵌套事务》.
分享到:
相关推荐
- `NESTED`:如果当前存在事务,则在嵌套事务内运行;如果没有事务,则行为类似于`REQUIRED`。 Spring事务管理的隔离级别包括: - `DEFAULT`:使用数据库的默认隔离级别。 - `READ_UNCOMMITTED`:最低隔离级别,...
嵌套事务允许独立于外部事务的回滚,但在外部事务回滚时,嵌套事务也会回滚。 #### 五、总结 通过上述分析,我们可以看出Spring中的事务传播行为提供了丰富的选项,可以帮助开发者精确地控制事务的执行逻辑。正确...
springboot mybatis多数据源加事务嵌套 事务之间的调用 回滚 亲测可用 定义2个库分别建立 CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户编号', `user_name` varchar(25) ...
在了解嵌套事务之前,可以先看下单个事务在 Spring 中的处理流程,以便后面可以更清晰地认识嵌套事务的逻辑。Spring 事务使用 AOP 的机制实现,会在@Transactional 注解修饰的方法前后分别织入开启事务的逻辑,以及...
4. **嵌套事务的深度**:理论上,你可以无限嵌套事务,但实际应用中应避免过深的嵌套,因为它可能导致性能问题,并增加代码的复杂性。 5. **事务隔离级别**:Nested事务继承了父事务的隔离级别,所以不需要额外设置...
7. **PROPAGATION_NESTED**:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则行为类似PROPAGATION_REQUIRED。 在`springTranscationDemo`中,我们可能会看到如何通过设置不同的传播行为来控制事务的...
7. **PROPAGATION_NESTED**:如果当前存在活动事务,则在嵌套事务中运行;如果没有活动事务,则按`PROPAGATION_REQUIRED`执行。这种传播行为仅对`DataSourceTransactionManager`有效。 #### 三、数据库隔离级别 ...
Spring事务实践 事务锁 嵌套事务设计原理
通过代码解析spring传播特性,包括 ... 如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。需要JDBC3.0以上支持。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 Spring事务管理创造性的解决了很多以前要用重量级的应用服务器才能解决的事务问题,那么...
- NESTED:如果当前存在事务,则在嵌套事务内执行;若无,则按REQUIRED行为处理。 #### 2.3 事务隔离级别 事务隔离级别是指并发事务间如何共享数据。Spring支持五种隔离级别: - READ_UNCOMMITTED:最低级别,可能...
这些传播行为可以帮助我们处理嵌套事务和其他复杂的事务场景。 另外,事务的隔离级别也是需要考虑的重要因素。Spring支持四种隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE,它们...
7. **PROPAGATION_NESTED**:如果当前存在事务,则在一个嵌套事务内执行;如果不存在,则行为与PROPAGATION_REQUIRED相同。 在"Spring事务传播Demo"中,我们可能看到如何在不同传播行为下,一个事务方法被另一个...
NEW(新建事务,如果已存在则挂起)、NOT_SUPPORTED(不支持事务,如果存在则挂起)、NEVER(永不运行在事务中)、NESTED(如果存在事务,则在嵌套事务内运行,否则新建)。 - 超时(timeout):定义事务可以运行的...
7. NESTED:如果当前存在事务,则在嵌套事务内执行;如果不存在,则按REQUIRED行为执行。 接下来,我们讨论事务的隔离级别。这是防止并发问题的关键策略,主要有以下四种: 1. READ_UNCOMMITTED:最低级别的隔离,...
如果当前存在事务,则暂停)、NOT_SUPPORTED(总是运行在非事务上下文中,如果当前存在事务,则暂停)、NEVER(如果当前存在事务,则抛出异常)、NESTED(如果当前存在事务,则创建一个嵌套事务;如果不存在,则按照...
嵌套事务可以实现细粒度的事务控制,尤其是在需要回滚部分操作而不影响整个事务时。 #### 二、Spring事务的隔离级别(Isolation) 事务的隔离级别定义了事务之间相互隔离的程度,从而影响事务的一致性。Spring支持四...
- `NESTED`:如果当前存在事务,则在一个嵌套事务内执行;如果没有事务,则按`REQUIRED`行为执行。 4. **事务的隔离级别** - `READ_UNCOMMITTED`:最低级别,可能导致脏读、不可重复读和幻读。 - `READ_...
- NESTED:如果当前存在事务,则创建一个嵌套事务;否则行为同REQUIRED。 理解并熟练掌握Spring声明式事务处理是每个Spring开发者必备的技能。正确地配置和使用事务管理能确保应用在处理复杂业务逻辑时保持数据的...