目录
一 Spring数据库的相关配置:
1 导入包:
2 配置数据库连接信息
3 可以直接使用:DataSource,JdbcTemplate
二 事务管理:
1 事务管理的实现
1.1 开启Spring事务管理
1.2 为指定方法添加事务
2 关键类与接口
2.1 事务拦截器(TransactionInterceptor)
2.2 事务管理器(PlatformTransactionManager)
3 属性
3.1 timeout 超时限制
3.2. readOnly 只读优化
3.3 rollbackFor 回滚指明
3.4 norollbackFor不回滚指明
3.5 propagation 事务的传播行为
3.6 小事务如果与大事务共用一个事务,那小事务按照大事务的属性设置,小事务的失效
三 内容补充
eg:具体使用举例
一 Spring数据库的相关配置:
1 导入包:
2 配置数据库连接信息
3 可以直接使用:DataSource,JdbcTemplate
二 事务管理:
1 声明式
声明式VS编程式
声明式:通过注解等方式,告诉框架,我需要做什么,框架会帮我做什么。
优点:代码量少
缺点:封装太多,排错不容易。
编程式:通过代码的方式,告诉框架,我要做什么,需要自己写代码实现。
优点:排错容易
缺点:代码量多
1 事务管理的实现
1.1 开启Spring事务管理
//开启事务
@EnableTransactionManagement
@SpringBootApplication
public class Spring03Application {public static void main(String[] args) {SpringApplication.run(Spring03Application.class, args);}}
1.2 为指定方法添加事务
2 关键类与接口
类/接口 | 作用 |
---|---|
PlatformTransactionManager | 事务操作的核心接口(提交、回滚等)。 |
TransactionInterceptor | 拦截方法调用,管理事务边界。(切面) |
TransactionAttributeSource | 解析@Transactional 的属性。 |
BeanFactoryTransactionAttributeSourceAdvisor | 将事务通知应用到目标方法。 |
InfrastructureAdvisorAutoProxyCreator | 自动生成代理对象的Bean后处理器。 |
2.1 事务拦截器(TransactionInterceptor)
-
拦截逻辑:代理对象会将方法调用委托给
TransactionInterceptor
(事务拦截器),该拦截器负责管理事务的开启、提交或回滚。 -
事务属性解析:拦截器会解析
@Transactional
注解的属性(如propagation
、isolation
、rollbackFor
等),决定事务的行为。
2.2 事务管理器(PlatformTransactionManager)
-
事务操作:拦截器通过
PlatformTransactionManager
接口(如DataSourceTransactionManager
、JpaTransactionManager
)执行具体的事务操作:-
getTransaction()
:根据传播行为决定是否创建新事务或加入现有事务。 -
commit()
:提交事务(如果当前是事务的发起者)。 -
rollback()
:回滚事务(在抛出异常时触发)。
-
3 属性
3.1 timeout 超时限制
(timeoutString也行)超时时间,事务超时,以秒为单位,一旦超过约定时间,事务就会回滚。
超时时间指的是从方法开始,到最后一次数据库操作的时间。
@Transactional(timeout = 10) // 单位:秒
public void doBusinessOperation() {// 业务逻辑
}
以下的sleep将不会计入超时时间的范畴
3.2. readOnly 只读优化
性能优化:通过声明只读事务提示底层资源进行优化,适用于纯查询场景。
合理使用readOnly=true
可以提升查询性能,但需结合具体技术栈验证其行为。
@Transactional(readOnly = true) // 默认为false
public List<User> findAllUsers() {// 查询逻辑(不应包含INSERT/UPDATE/DELETE)
}
3.3 rollbackFor 回滚指明
通过rollbackFor
自定义事务回滚的异常条件,覆盖默认行为。
-
精确控制回滚条件:允许开发者明确指定某些特定异常(包括受检异常)触发事务回滚。
-
覆盖默认行为:默认仅回滚未检查异常,通过
rollbackFor
可扩展或替换默认规则。
异常类型 | 示例 | 默认是否触发回滚 | 说明 |
---|---|---|---|
运行时异常(Unchecked) | RuntimeException 、NullPointerException 、IllegalArgumentException | 是 | 继承自RuntimeException |
错误(Error) | OutOfMemoryError 、StackOverflowError | 是 | 继承自Error |
编译时异常(Checked) | IOException 、SQLException | 否 | 继承自Exception (非RuntimeException) |
由此我们使用回滚指明rollbackfor来调控回滚的时机
3.4 norollbackFor不回滚指明
-
核心作用:通过
noRollbackFor
精准控制哪些异常不触发事务回滚,即使它们是默认回滚类型。 -
适用场景:
-
需要忽略特定的非致命异常(如业务警告、预期内的错误)。
-
覆盖框架或默认的异常回滚策略。
-
-
关键原则:
-
明确异常类型,避免过度使用(如直接排除
Exception.class
可能导致数据不一致)。 -
结合
rollbackFor
实现精细化的事务控制。 -
noRollbackFor
优先级高于rollbackFor
:
-
3.5 propagation 事务的传播行为
传播行为类型及作用(小事务与大事务的绑定关系)
传播行为 | 描述 | 适用场景 |
---|---|---|
REQUIRED (默认) | 如果当前存在事务,则加入该事务;否则新建一个事务。 | 多数业务场景(如订单创建、库存扣减)。 |
SUPPORTS | 如果当前存在事务,则加入;否则以非事务方式运行。 | 查询方法,允许在事务或非事务上下文中执行。 |
MANDATORY | 必须在已有事务中运行,否则抛出异常。 | 强制要求调用方必须开启事务(如核心业务操作)。 |
REQUIRES_NEW | 无论当前是否存在事务,都新建一个独立事务,挂起当前事务(若存在)。 | 需要独立提交的操作(如日志记录、异步任务)。 |
NOT_SUPPORTED | 以非事务方式执行,若当前存在事务,则挂起当前事务。 | 不依赖事务的操作(如纯查询或外部接口调用)。 |
NEVER | 必须在非事务环境下执行,否则抛出异常。 | 严格禁止事务的场合(如某些性能敏感操作)。 |
| 在已有事务中嵌套一个子事务(通过保存点实现),子事务可独立回滚。 | 部分操作需要独立回滚(如批量处理中的单条失败)。仅部分数据库支持(如MySQL的InnoDB)。 |
3.6 小事务如果与大事务共用一个事务,那小事务按照大事务的属性设置,小事务的失效
1 传播行为:
若小事务的传播行为为REQUIRED
(默认),当它被大事务调用时,会直接加入大事务,而非创建新事务。
@Transactional(timeout = 30) // 大事务
public void bigTransaction() {smallTransaction(); // 小事务
}@Transactional(timeout = 10) // 小事务(实际无效)
public void smallTransaction() {// 操作数据库
}
2. 小事务“失效”的具体表现
事务属性 | 失效原因 |
---|---|
超时(Timeout) | 大事务的timeout 决定了整个事务的最长执行时间,小事务的timeout 设置无效。 |
隔离级别(Isolation) | 事务的隔离级别在事务开始时确定,小事务无法修改已存在事务的隔离级别。 |
只读(ReadOnly) | 若大事务为读写模式,小事务的readOnly=true 不生效(数据库连接仍为读写模式)。 |
三 内容补充
eg:实现方法
下面这种情况金额减了但是库存没有减,扣减金额跟随大事务,扣减库存开启自己的事务自己干
eg:具体使用举例
1 如果在上述位置放置运行时异常,那么根据分析:
C I J D K L F H N - 都是好的可以正常运行
2 如果在 L方法位置放置运行时异常,那么根据分析:
F H C I J K 都是好的可以正常 ( E这一段代码执行不到 )
3 如果在 M方法位置放置运行时异常,那么根据分析:
F H C I J D K L 都是好的可以正常运行
1. REQUIRED
(默认)
比喻场景:团队合作做项目
-
行为:
-
如果你加入时已经有团队在做项目(存在事务),你就直接跟着团队一起干(加入事务)。
-
如果没人开始做(无事务),你就自己拉起一个团队(新建事务)。
-
-
总结:能跟团就跟团,没团就自己组队。
2. SUPPORTS
比喻场景:朋友聚餐AA制
-
行为:
-
如果大家决定AA制(存在事务),你就跟着一起AA(加入事务)。
-
如果没人提AA(无事务),你就自己单独付钱(非事务运行)。
-
-
总结:有团就随大流,没团就自己玩。
3. MANDATORY
比喻场景:必须团队合作的任务
-
行为:
-
必须有人组队(存在事务)才能执行任务,否则直接罢工(抛出异常)。
-
比如公司规定某些任务必须集体完成,不允许单干。
-
-
总结:没团队就罢工。
4. REQUIRES_NEW
比喻场景:临时插队的紧急任务
-
行为:
-
无论你手头有没有任务(无论是否存在事务),都要暂停当前工作(挂起事务),先处理这个紧急任务(新建独立事务)。
-
例如:正在写报告时,老板突然让你立刻发一封邮件(独立事务),发完邮件再继续写报告。
-
-
总结:天大的事也得先干我这个。
5. NOT_SUPPORTED
比喻场景:去图书馆自习
-
行为:
-
你不想被其他人的讨论影响(挂起当前事务),选择自己安静看书(非事务运行)。
-
例如:在团队开会时(存在事务),你突然去走廊接电话(非事务)。
-
-
总结:谁都别打扰我,我要自己静静。
6. NEVER
比喻场景:严禁团队合作的考试
-
行为:
-
必须独自完成考试(非事务),如果发现有人组队作弊(存在事务),直接取消资格(抛出异常)。
-
-
总结:敢组队就挂科。
7. NESTED
比喻场景:项目中的子任务
-
行为:
-
你在做一个大项目(外层事务),中途画了一部分设计稿(创建保存点)。
-
如果设计稿有问题(子事务失败),可以只重画这部分(回滚到保存点),而不用推翻整个项目。
-
-
总结:大项目里的小草稿,错了只改这一页。