当前位置: 首页 > backend >正文

从并发问题衍生出的Spring的七种事务传播行为

最近在处理一个BPM流程时,遇到了并发问题,原因是事务粒度太大了,导致等待lock超时。今天刚好借此机会分享下Spring框架中提供的7种事务传播行为。

在 Spring中,@Transactional 注解支持配置事务的传播行为,用于指定当一个事务方法被另一个事务方法调用时,如何处理事务边界。Spring 定义了 7 种传播行为。

1. Propagation.REQUIRED (默认值)

这是最常用的传播行为,也是 @Transactional 注解的默认设置。

它保证了方法总是在一个事务中执行。如果内部方法加入外部方法的事务,它们将共享同一个事务上下文,内部方法的失败会导致整个事务回滚。

@Service
public class MyService {// 默认 REQUIRED,一组操作要么同时成功,要么同时失败。@Transactionalpublic void defaultTx() {}
}

2. Propagation.SUPPORTS

这个方法不强制需要事务。如果调用它的上下文有事务,它就利用这个事务;如果没有,它也不创建新的事务。

@Service
public class MyService {// 支持事务,无则非事务执行@Transactional(propagation = Propagation.SUPPORTS)public void supportsTx() {}
}

3. Propagation.MANDATORY

强制要求方法必须在一个已存在的事务中执行。如果调用者没有启动事务,调用该方法会失败。

@Service
public class MyService {// 必须存在事务,否则抛异常@Transactional(propagation = Propagation.MANDATORY)public void mandatoryTx() {}
}

4. Propagation.REQUIRES_NEW

内部方法的事务与外部方法的事务是完全独立的。

内部事务的提交或回滚不影响外部事务。同样,外部事务的回滚也不会影响已提交的内部事务。

@Service
public class MyService {// 新建事务,挂起外层事务@Transactional(propagation = Propagation.REQUIRES_NEW)public void requiresNewTx() {}
}

5. Propagation.NOT_SUPPORTED

明确表示该方法不应在事务中运行。

如果调用它时存在事务,该事务会被暂停,直到该方法执行完毕。

@Service
public class MyService {// 不支持事务,存在事务时挂起,适用于数据批量导出、日志写入操作@Transactional(propagation = Propagation.NOT_SUPPORTED)public void notSupportedTx() {}
}

6. Propagation.NEVER

强制要求方法不能在任何事务中执行。如果检测到当前存在事务,会立即报错。

@Service
public class MyService {// 不支持事务,存在事务时抛异常@Transactional(propagation = Propagation.NEVER)public void neverTx() {}
}

7. Propagation.NESTED

嵌套事务是外部事务的一个子事务。它有自己的保存点 (savepoint)。

内部嵌套事务可以独立于外部事务进行回滚(回滚到保存点),但它的最终提交依赖于外部事务的成功提交。如果外部事务回滚,则嵌套事务的所有更改也会被回滚。

@Service
public class MyService {// 嵌套事务,依赖外层事务@Transactional(propagation = Propagation.NESTED)public void nestedTx() {}
}

与REQUIRES_NEW 不同的地方在于,前者创建的是完全独立的事务,而 NESTED 创建的是依赖于外部事务的子事务(使用保存点)。

NESTED 行为依赖于底层 DataSource 和事务管理器(PlatformTransactionManager)是否支持保存点。并非所有数据库和 JDBC 驱动都支持。

http://www.xdnf.cn/news/1516.html

相关文章:

  • 4.7 字符串到整形的相互转换
  • 机器学习分类算法详解:原理、应用场景与测试用例
  • 深入理解 Python 协程:单线程下的高效并发方案
  • JWT的token泄露要如何应对
  • 关于编译原理——语义翻译器的设计
  • 异构迁移学习(无创脑机接口中的跨脑电帽迁移学习)
  • 开发体育直播系统后台权限设计实践分享|ThinkPHP 技术栈落地案例
  • -PHP 反序列化POP 链构造魔术方法流程漏洞触发条件属性修改
  • 开源版「v0」OpenUI:根据文本生成UI界面代码
  • Sqlserver 自增长id 置零或者设置固定值
  • 【工具变量】各市ZF数字治理指标数据集(2001-2024年)
  • RabbitMQ 详解(核心概念)
  • 什么是回表?
  • A2A协议实现概览:多语言生态系统的蓬勃发展
  • vue项目中使用tinymce富文本编辑器
  • 楼宇自控系统如何打破传统桎梏,为建筑管理开创全新思路
  • 京东商品详情数据 API 接口讨论学习
  • Python内置函数---bytearray()
  • 八大排序算法
  • git pull的时候报错
  • 主流开源 LLM 应用开发平台详解
  • 记录下递归
  • 0.(新专栏目录)数据分类的艺术:从理论到实践的全面指南
  • 结构型模式:适配器模式
  • java后端开发day35--集合进阶(四)--双列集合:MapHashMapTreeMap
  • leetcode 二分查找应用
  • Linux/AndroidOS中进程间的通信线程间的同步 - IPC方式简介
  • Podman Desktop:现代轻量容器管理利器(Podman与Docker)
  • 基于stm32的智能门锁系统
  • ecovadis评估注意事项?ecovadis评估过程需要多长时间