Java外功精要(6)——Spring事务及其传播机制

Java外功精要(6)——Spring事务及其传播机制

1.概述

Spring事务管理是Spring框架中用于确保数据库操作 原子性、一致性、隔离性和持久性(ACID)
的核心机制。它通过声明式编程式(本文略)方式管理事务,支持多种事务传播行为和隔离级别相较于编程式事务,声明式事务通过@Transactional注解实现事务管理,无需手动编写事务代码事务基本概念在全面解析MySQL(5)——“索引、事务、JDBC”三大核心一文中有介绍,本文不再赘述

2.@Transactional

作用:提供声明式事务管理。它简化了在应用程序中管理数据库事务的流程。开发者只需在方法或类上添加此注解,Spring框架就会自动处理事务的开启、提交和回滚,无需手动编写事务管理代码(如 begin、commit、rollback)
级别:类 + 方法作为类注解:为类中所有public方法添加注解作为方法注解:默认仅对public方法生效
@RequestMapping("/test")@RestController@Slf4jpublicclassTestController{privatefinalUserService userService;@AutowiredpublicTestController(UserService userService){this.userService = userService;}@Transactional@RequestMapping("/test1")publicStringtest1(String userName,String password){UserInfo userInfo =newUserInfo(); userInfo.setUserName(userName); userInfo.setPassword(password);Integer result = userService.register(userInfo);if(result ==1){ log.info("test1注册成功,userName:{},password:{}", userName, password);}return"注册成功";}}
使用PostMan向后端发送请求:
MySQL查询结果如下:

后端日志日志如下:

2.1 rollbackfor

作用:指定哪些异常触发回滚,默认情况下在抛出 非受查异常(RuntimeException)/错误(Error) 时触发回滚

指定回滚类型

@RequestMapping("/test")@RestController@Slf4jpublicclassTestController{privatefinalUserService userService;@AutowiredpublicTestController(UserService userService){this.userService = userService;}@Transactional(rollbackFor =Exception.class)@RequestMapping("/test4")publicStringtest4(String userName,String password)throwsIOException{UserInfo userInfo =newUserInfo(); userInfo.setUserName(userName); userInfo.setPassword(password);Integer result = userService.register(userInfo);if(result ==1){ log.info("test4注册成功,userName:{},password:{}", userName, password);thrownewIOException();}return"注册成功";}}
使用PostMan向后端发送请求:
MySQL查询结果如下:

后端日志日志如下:

抛出非受查异常时

@RequestMapping("/test")@RestController@Slf4jpublicclassTestController{privatefinalUserService userService;@AutowiredpublicTestController(UserService userService){this.userService = userService;}@Transactional@RequestMapping("/test3")publicStringtest3(String userName,String password){UserInfo userInfo =newUserInfo(); userInfo.setUserName(userName); userInfo.setPassword(password);Integer result = userService.register(userInfo);if(result ==1){ log.info("test3注册成功,userName:{},password:{}", userName, password);thrownewRuntimeException();}return"注册成功";}}
使用PostMan向后端发送请求:
MySQL查询结果如下:

后端日志日志如下:

抛出受查异常时

@RequestMapping("/test")@RestController@Slf4jpublicclassTestController{privatefinalUserService userService;@AutowiredpublicTestController(UserService userService){this.userService = userService;}@Transactional@RequestMapping("/test2")publicStringtest2(String userName,String password)throwsIOException{UserInfo userInfo =newUserInfo(); userInfo.setUserName(userName); userInfo.setPassword(password);Integer result = userService.register(userInfo);if(result ==1){ log.info("test2注册成功,userName:{},password:{}", userName, password);thrownewIOException();}return"注册成功";}}
使用PostMan向后端发送请求:
MySQL查询结果如下:

后端日志日志如下:

2.2 isolation

作用:用于指定事务的隔离级别Isolation.DEFAULT:使用底层数据库默认的隔离级别Isolation.READ_UNCOMMITTED:读未提交Isolation.READ_COMMITTED:读已提交Isolation.REPEATABLE_READ:可重复读Isolation.SERIALIZABLE:串行化每种隔离级别的具体效果在全面解析MySQL(5)——“索引、事务、JDBC”三大核心一文中有介绍,本文不再赘述

2.3 propagation

作用:用于定义事务的传播行为,即当前事务方法被另一个事务方法调用时,事务应如何传播。Spring提供了7种传播行为,均基于Propagation枚举类实现

2.3.1 Propagation.REQUIRED

默认传播行为。如果当前存在事务,则加入该事务;如果不存在事务,则新建一个事务

2.3.2 Propagation.SUPPORTS

如果当前存在事务,则加入该事务;如果不存在事务,则以非事务方式执行

2.3.3 Propagation.MANDATORY

强制要求当前存在事务并加入,否则抛出异常

2.3.4 Propagation.REQUIRES_NEW

无论当前是否存在事务,都新建一个事务。新事务与当前事务独立,互不干扰

2.3.5 Propagation.NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,则挂起该事务

2.3.6 Propagation.NEVER

强制要求当前不能存在事务,否则抛出异常

2.3.7 Propagation.NESTED

如果当前存在事务,则在嵌套事务中执行;如果不存在事务,则行为与Propagation.REQUIRED相同。嵌套事务的回滚不影响外部事务,但外部事务回滚会导致嵌套事务回滚(适用于需要部分回滚的场景)

3.Gitee

Gitee地址:九转苍翎
本文源码:spring-trans

Read more

Python RESTful API设计终极指南:从理论到企业级实战

Python RESTful API设计终极指南:从理论到企业级实战

目录 摘要 1 引言:为什么RESTful API设计如此重要 1.1 RESTful API的核心价值定位 1.2 RESTful API演进路线图 2 RESTful API设计核心技术原理 2.1 资源设计哲学与实践 2.1.1 资源识别与建模 2.1.2 资源关系建模 2.2 统一接口原则深度解析 2.2.1 HTTP方法语义化使用 2.2.2 状态码语义化设计 2.3 HATEOAS超媒体驱动设计 2.3.1 HATEOAS原理与实现 2.3.2 HATEOAS客户端工作流程

By Ne0inhk
Python 列表内存存储本质:存储差异原因与优化建议

Python 列表内存存储本质:存储差异原因与优化建议

文章目录 * 1. 问题引入:列表存储的内存 "膨胀" * 2. 理论存储与实际存储的差异 * 2.1 64位整数的存储差异 * 2.2 短字符串的存储差异 * 3. 列表的内存存储本质 * 3.1 相同元素列表内存少的核心原因:对象复用 * 3.1.1 小整数的缓存复用机制 * 3.1.2 字符串的驻留(Intern)机制 * 3.2 不同元素列表内存高的原因:对象重复创建 * 3.2.1 不同整数的内存开销 * 3.2.2 不同字符串的内存开销 * 4. 内存占用对比分析 * 5. 优化建议:利用对象复用减少内存开销 * 6. 总结

By Ne0inhk
C++可变参数队列与压栈顺序:从模板语法到汇编调用约定的深度解析

C++可变参数队列与压栈顺序:从模板语法到汇编调用约定的深度解析

C++可变参数队列与压栈顺序:从模板语法到汇编调用约定的深度解析 本文聚焦一个具体而关键的技术主题:C++ 可变参数模板(Variadic Templates)。我们将从现代 C++ 的优雅写法出发,深入剖析其在 x86-64 架构下的真实行为,特别澄清一个长期被误解的核心问题——可变参数是否“从右向左压栈”?它们在寄存器和栈中究竟是如何排布的? 如果你正在实现一个类型安全的消息队列、日志系统或任务调度器,并希望理解 enqueue(1, "hello", 3.14) 这行代码在 CPU 层面到底发生了什么,那么这篇文章就是为你量身打造的。 一、引言:可变参数 ≠ va_list —— 一场范式革命 很多初学者将 C++ 的可变参数模板与 C 语言的 va_list 混为一谈。这是重大误区,甚至会导致错误的性能假设和安全漏洞。 1.1

By Ne0inhk