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

【Spring Boot 事务管理】

Spring Boot 事务管理

  • 一、Spring Boot中的事务管理
    • 1.声明式事务管理
      • @Transactional注解
        • 基本使用
        • 配置选项
    • 2.编程式事务管理
      • TransactionTemplate
      • PlatformTransactionManager
  • 二、@Transactional注解深入
    • 1.基本使用
      • 基本属性
    • 2.传播行为
    • 3.隔离级别
    • 4.事务超时设置
    • 5.回滚规则
  • 三、事务管理的最佳实践
    • 1.事务边界的确定
    • 2.只读事务的使用
    • 3.避免编程式事务

一、Spring Boot中的事务管理

1.声明式事务管理

@Transactional注解

Spring最常用的事务管理方式是声明式事务管理,主要通过@Transactional注解实现。这种方式的优点在于简单易用,通过将注解添加到类或方法上,开发者可以轻松地控制事务的边界,而无需直接与底层的事务管理API打交道。

基本使用

在方法级别上使用@Transactional注解,可以确保该方法内的所有操作要么全部成功,要么在遇到异常时全部回滚。

import org.springframework.transaction.annotation.Transactional;@Transactional
public void updateUserData(User user) {// 这里的数据库操作会在一个事务中执行
}
配置选项

@Transactional注解提供了多种配置选项,包括事务的传播行为、隔离级别、超时设置等。

2.编程式事务管理

使用TransactionTemplate或直接使用PlatformTransactionManager,可以在代码中精确控制事务的边界。

TransactionTemplate

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionTemplate;public class UserService {@Autowiredprivate TransactionTemplate transactionTemplate;public User createUser(final User user) {return transactionTemplate.execute(status -> {// 这里的操作会在一个事务中执行return userRepository.save(user);});}
}

PlatformTransactionManager

对于需要完全控制事务行为的场景,Spring还允许直接使用PlatformTransactionManager。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;public class UserServiceImpl implements UserService {@Autowiredprivate PlatformTransactionManager transactionManager;public void updateUser(User user) {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// 这里的操作会在一个事务中执行userRepository.update(user);transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);throw e;}}
}

二、@Transactional注解深入

1.基本使用

@Transactional注解可以应用于类或方法级别。当应用于类级别时,该类中的所有公共方法都会被应用事务管理。当应用于方法级别时,只有标注了该注解的方法才会进行事务管理。

基本属性

  • readOnly: 指定事务是否为只读事务。只读事务可以帮助数据库引擎优化事务。
  • propagation: 指定事务的传播行为。
  • isolation: 指定事务的隔离级别。
  • timeout: 定义事务的超时限制(以秒为单位)。
  • rollbackFor: 指定哪些异常可以触发事务回滚。
  • noRollbackFor: 指定哪些异常不应触发事务回滚。

2.传播行为

事务的传播行为定义了事务边界的创建方式。Spring定义了多种传播行为:

  • REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
  • MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • REQUIRES_NEW: 总是创建一个新的事务,如果当前存在事务,则挂起当前事务。
  • NOT_SUPPORTED: 总是以非事务方式执行,如果当前存在事务,则挂起当前事务。
  • NEVER: 总是以非事务方式执行,如果当前存在事务,则抛出异常。
  • NESTED: 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则表现同REQUIRED

3.隔离级别

隔离级别定义了一个事务可能受其他并发事务影响的程度。Spring支持以下隔离级别:

  • DEFAULT: 使用底层数据源的默认隔离级别。
  • READ_UNCOMMITTED: 允许读取未提交的更改。
  • READ_COMMITTED: 仅允许读取已提交的更改。
  • REPEATABLE_READ: 确保在事务内重复读取同一记录的结果一致。
  • SERIALIZABLE: 完全隔离,确保事务串行化执行。

4.事务超时设置

通过@Transactional注解的timeout属性,可以为事务指定超时时间。如果事务执行时间超过了指定的时间限制,Spring将自动回滚事务。

5.回滚规则

通过@Transactional注解的rollbackFornoRollbackFor属性,可以精确控制异常回滚行为:

  • rollbackFor: 指定哪些异常应该触发事务回滚。
  • noRollbackFor: 指定哪些异常不应该触发事务回滚。

三、事务管理的最佳实践

1.事务边界的确定

事务边界定义了事务的开始和结束,合理的事务边界可以确保事务既不过大也不过小。

  • 定义清晰的业务逻辑单元:每个事务应该对应一个清晰定义的业务逻辑单元。不应该让一个事务覆盖多个不相关的操作。
  • 避免长事务:长事务会占用数据库资源,增加锁定的范围和时间,从而影响并发性能。尽量避免不必要的长事务,及时提交或回滚。
  • 事务中的操作数量:虽然理论上事务可以包含任意数量的操作,但是在实践中,应该避免在单一事务中包含过多的操作。如果业务逻辑允许,可以将一个大事务分解为几个小事务,以提高并发性和系统稳定性。

2.只读事务的使用

只读事务是指不包含任何修改(插入、更新、删除)操作的事务。只读事务的使用有以下好处:

  • 性能优化:数据库可以对只读事务进行优化,如减少锁的使用,提升查询性能。
  • 减少副作用:标记为只读的事务明确告诉数据库和应用程序这个事务不会修改数据,有助于避免由于错误的数据修改导致的问题。

何时使用只读事务:

  • 数据查询操作:当事务仅包含数据查询操作,不涉及任何数据修改时,应将事务标记为只读。
  • 报表生成:生成报表或执行大量查询以分析数据时,使用只读事务可以提高效率。

3.避免编程式事务

尽管Spring提供了编程式事务管理的能力,但在大多数情况下,推荐使用声明式事务管理(@Transactional注解)原因如下:

  • 简化开发:声明式事务管理通过注解的方式,减少了编程的复杂度,使得事务管理更加直观和易于理解。
  • 减少代码侵入性:使用声明式事务管理,事务代码与业务代码分离,降低了代码的耦合度,提高了代码的可读性和可维护性。
  • 统一事务管理:声明式事务管理提供了一种统一的事务管理机制,使得事务管理更加标准化,易于跟踪和维护。
http://www.lryc.cn/news/389143.html

相关文章:

  • 【C++】C++指针在线程中调用与受保护内存空间读取方法
  • 安全隔离上网的有效途径:沙箱
  • jenkins下后台运行链接Jenkins服务脚本方法
  • 宠物空气净化器哪个品牌性价比高?宠物空气净器Top3品牌推荐
  • 苏州大厂面试题JAVA 面试集
  • 数据库取出来的日期格式是数组格式,序列化日期格式
  • 【Android】创建一个可以在屏幕上拖动的悬浮窗
  • SPI NAND、SD NAND和eMMC对比—MK米客方德
  • “深入解析:YUM仓库、RPM包与源码编译——Linux软件安装方式全面对比“
  • 中电金信:银行业私有云何去何从
  • Adobe Acrobat Pro或者Adobe Acrobat Reader取消多标签页显示,设置打开一个pdf文件对应一个窗口。
  • 从0开始学习pyspark--pyspark的数据读取[第4节]
  • 极速升级:MacOS系统中Pip源的切换指南
  • 服务器的分类,主流服务器的应用场景
  • Objects and Classes (对象和类)
  • 从单点到全景:视频汇聚/安防监控EasyCVR全景视频监控技术的演进之路
  • Java学习 -Golang开发环境+目录结构+编译+部署
  • Redis 典型应用——缓存(缓存预热,穿透,雪崩,击穿)
  • Sharding-JDBC分库分表的基本使用
  • 7月信用卡新规下:信用卡欠的钱不用还了?
  • 坑——python的redis库的decode_responses设置
  • 从项目中学习Bus-Off的快慢恢复
  • 视频参考帧和重构帧复用
  • js修改scss变量
  • 【中霖教育怎么样】报考注册会计师有年龄限制吗?
  • PHP验证日本手机电话号码
  • Qt 配置ASan
  • MySQL常用操作命令大全
  • 有人物联的串口服务器USR-TCP232-410S基本测试通信和使用方案(485串口和232串口)
  • 二维码登录的原理