Spring 事务

发布时间:2026/9/15 22:55:18

Spring 事务 我们在实际业务场景中经常会遇到数据频繁修改读取的问题。在同一时刻不同的业务逻辑对同一个表数据进行修改这种冲突很可能造成数据不可挽回的错乱所以我们需要用事务来对数据进行管理。一、事务的概念事务必须服从ACID原则。ACID指的是原子性atomicity、一致性consistency、隔离性isolation和持久性durability。通俗理解事务其实就是一系列指令的集合。原子性操作这些指令时要么全部执行成功要么全部不执行。只要其中一个指令执行失败所有的指令都执行失败数据进行回滚回到执行指令前的数据状态。一致性事务的执行使数据从一个状态转换为另一个状态但是对于整个数据的完整性保持稳定。隔离性在该事务执行的过程中无论发生的任何数据的改变都应该只存在于该事务之中对外界不存在任何影响。只有在事务确定正确提交之后才会显示该事务对数据的改变。其他事务才能获取到这些改变后的数据。持久性当事务正确完成后它对于数据的改变是永久性的。二、并发事务导致的问题第一类丢失更新撤销一个事务时把其他事务已提交的更新数据覆盖。脏读一个事务读取到另一个事务未提交的更新数据。幻读一个事务执行两次查询第二次结果集包含第一次中没有或某些行已经被删除的数据造成两次结果不一致只是另一个事务在这两次查询中间插入或删除了数据造成的。不可重复读一个事务两次读取同一行的数据结果得到不同状态的结果中间正好另一个事务更新了该数据两次结果相异不可被信任。第二类丢失更新是不可重复读的特殊情况。如果两个事物都读取同一行然后两个都进行写操作并提交第一个事物所做的改变就会丢失。三、编程式事务管理和声明式事务管理编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理spring推荐使用TransactionTemplate。声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截然后在目标方法开始之前创建或者加入一个事务在执行完目标方法之后根据执行情况提交或者回滚事务。最大的优点就是不需要通过编程的方式管理事务这样就不需要在业务逻辑代码中掺杂事务管理的代码只需在配置文件中做相关的事务规则声明(或通过基于Transactional注解的方式)便可以将事务规则应用到业务逻辑中。缺点是粒度只能作用到方法级别。声明式事务管理常用的方式一种是基于tx和aop名字空间的xml配置文件另一种就是基于Transactional注解。显然基于注解的方式更简单易用更清爽。四、spring事务特性spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口其中TransactionDefinition接口定义以下特性事务隔离级别隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition 接口中定义了五个表示隔离级别的常量TransactionDefinition.ISOLATION_DEFAULT这是默认值表示使用底层数据库的默认隔离级别。对大部分数据库而言通常这值就是TransactionDefinition.ISOLATION_READ_COMMITTED。TransactionDefinition.ISOLATION_READ_UNCOMMITTED该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读不可重复读和幻读因此很少使用该隔离级别。比如PostgreSQL实际上并没有此级别。TransactionDefinition.ISOLATION_READ_COMMITTED该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读这也是大多数情况下的推荐值。TransactionDefinition.ISOLATION_REPEATABLE_READ该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询并且每次返回的记录都相同。该级别可以防止脏读和不可重复读。TransactionDefinition.ISOLATION_SERIALIZABLE所有的事务依次逐个执行这样事务之间就完全不可能产生干扰也就是说该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。事务传播行为所谓事务的传播行为是指如果在开始当前事务之前一个事务上下文已经存在此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量TransactionDefinition.PROPAGATION_REQUIRED如果当前存在事务则加入该事务如果当前没有事务则创建一个新的事务。这是默认值。TransactionDefinition.PROPAGATION_REQUIRES_NEW创建一个新的事务如果当前存在事务则把当前事务挂起。TransactionDefinition.PROPAGATION_SUPPORTS如果当前存在事务则加入该事务如果当前没有事务则以非事务的方式继续运行。TransactionDefinition.PROPAGATION_NOT_SUPPORTED以非事务方式运行如果当前存在事务则把当前事务挂起。TransactionDefinition.PROPAGATION_NEVER以非事务方式运行如果当前存在事务则抛出异常。TransactionDefinition.PROPAGATION_MANDATORY如果当前存在事务则加入该事务如果当前没有事务则抛出异常。TransactionDefinition.PROPAGATION_NESTED如果当前存在事务则创建一个事务作为当前事务的嵌套事务来运行如果当前没有事务则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。事务超时所谓事务超时就是指一个事务所允许执行的最长时间如果超过该时间限制但事务还没有完成则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间其单位是秒。默认设置为底层事务系统的超时值如果底层数据库事务系统没有设置超时值那么就是none没有超时限制。事务只读属性只读事务用于客户代码只读但不修改数据的情形只读事务用于特定情景下的优化比如使用Hibernate的时候。默认为读写事务。“只读事务”并不是一个强制选项它只是一个“暗示”提示数据库驱动程序和数据库系统这个事务并不包含更改数据的操作那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化比方说不安排相应的数据库锁以减轻事务对数据库的压力毕竟事务也是要消耗数据库的资源的。但是你非要在“只读事务”里面修改数据也并非不可以只不过对于数据一致性的保护不像“读写事务”那样保险而已。因此“只读事务”仅仅是一个性能优化的推荐配置而已并非强制你要这样做不可spring事务回滚规则指示spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。spring事务管理器会捕捉任何未处理的异常然后依据规则决定是否回滚抛出异常的事务。默认配置下spring只有在抛出的异常为运行时unchecked异常时才回滚该事务也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚)而抛出checked异常则不会导致事务回滚。可以明确的配置在抛出那些异常时回滚事务包括checked异常。也可以明确定义那些异常抛出时不回滚事务。还可以编程性的通过setRollbackOnly()方法来指示一个事务必须回滚在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。
延伸阅读

更多相关文章

2026/9/10 3:42:57

基于Centos+uWSGI+Nginx部署Django项目(过程非常详细)

部署背景:之前开发了一个本地的个人blog项目,还未部署云服务器,有些功能还未完善,先尝试在本地部署。本篇内容则是基于centos+uwsgi+nginx来部署项目,实现高性能web服务,其中还给出uwsgi和nginx分别部署在不同服务器上步骤,这一点,很多文章并未给出相关探讨。 文章目录…

2026/9/15 22:12:25

tf.app.flags.FLAGS与tf.app.flags.DEFINE_string()用法

举个栗子 新建test.py文件,并输入如下代码,代码的功能是创建几个命令行参数,然后把命令行参数输出显示 import tensorflow as tf FLAGStf.app.flags.FLAGS tf.app.flags.DEFINE_float(flag_float, 0.01, input a float) tf.app.flags.DEFINE…

2026/9/15 19:59:12

从源码构建Frida编译环境:解决Android定制与兼容性问题

1. 项目概述:为什么我们需要一个自定义的Frida编译环境? 如果你正在阅读这篇文章,大概率已经和Frida打过交道了。无论是移动安全分析、应用动态插桩,还是逆向工程,Frida都是一个绕不开的神器。它那句“Dynamic instrum…

2026/9/15 22:53:55

安卓投屏到电脑:两种连接方式,10 分钟跑通 Escrcpy

安卓投屏到电脑:两种连接方式,10 分钟跑通 Escrcpy 【免费下载链接】escrcpy 📱 Display and control your Android device graphically with scrcpy. 项目地址: https://gitcode.com/GitHub_Trending/es/escrcpy Escrcpy 把 scrcpy 做…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码