求求你,别再乱用@Transactional了

2024-01-09 20:36
文章标签 transactional 求求

本文主要是介绍求求你,别再乱用@Transactional了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

求求你,别再乱用@Transactional了

文章目录

    • 🔊先看个问题
      • 📕情况1
        • 情况1结果
      • 🖥️情况2
        • 情况2结果
      • 📜 情况三
        • 情况3结果
      • 📘情况4
        • 情况4结果
    • 🔖先说结论
      • 情况1结果
      • 情况2结果
      • 情况3结果
      • 情况4结果
      • 📚7种传播行为
    • 🖊️最后总结

🔊先看个问题

你觉得test2方法执行后 user1表有几条数据?

📕情况1

image-20240108105311811

情况1结果

三条记录都保存成功了

image-20240108105636368

🖥️情况2

catch中throw出异常

image-20240108105751276

情况2结果

没有数据

image-20240108105859134

📜 情况三

去掉test2中的@transactional 与catch中的throw异常

image-20240108133805659

情况3结果

三条都保存了

image-20240108110509736

img

📘情况4

使用依赖注入方式调用all

image-20240108110616422

情况4结果

两条数据 id为3,4的出现异常 回滚了,其他正常保存

image-20240108110726046

铁子们,怎么样,此时你的表情是这样的

image-20240108111157423

还是这样的

img

是不是脑瓜子嗡嗡的😂,不要慌,这就给你们解密哈

🔖先说结论

情况1结果

只有一个事务,就是test2上的

image-20240108111726687

情况2结果

只有一个事务,就是test2上的,i=1的记录报错了,导致事务最终回滚,三条记录都不保存

image-20240108112023947

情况3结果

根本没有事务!!!!!

???为什么?why?what 发科??😳

img

-》因为all方法是this调用;为什么this调用就不会用到事务呢,不要慌,后面会详细解释的哈

image-20240108112204153

情况4结果

存在三个独立事务,都是all方法发起的,因为调用all方法是通过注入的方式调用,所以会产生事务

image-20240108112713559

兄弟们,脑壳不要打铁,忘掉刚刚的所有,无招胜有招,看一看下面的魔术揭秘,看完你就会评论区留言,小编这啥小儿科问题,太简单了,so easy,哈哈哈哈😄

img

1、首先讲解下spring中是怎么处理事务的

spring声明式事务是通过事务拦截器TransactionInterceptor拦截目标方法,来实现事务管理的功能的,事务管理器处理过程大致如下:

1、获取事务管理器
2、通过事务管理器开启事务
try{3、调用业务方法执行db操作4、提交事务
}catch(RuntimeException | Error){5、回滚事务
}

2、何时事务会回滚?

默认情况下,目标方法抛出RuntimeException或者Error的时候,事务会被回滚。

3、Spring事务管理器中的Connection和业务中操作db的Connection如何使用同一个的?

以DataSourceTransactionManager为事务管理器,操作db使用JdbcTemplate来说明一下。

创建DataSourceTransactionManager和JdbcTemplate的时候都需要指定dataSource,需要将他俩的dataSource指定为同一个对象。

当事务管理器开启事务的时候,会通过dataSource.getConnection()方法获取一个db连接connection,然后会将dataSource->connection丢到一个Map中,然后将map放到ThreadLocal中。

当JdbcTemplate执行sql的时候,以JdbcTemplate.dataSource去上面的ThreadLocal中查找,是否有可用的连接,如果有,就直接拿来用了,否则调用JdbcTemplate.dataSource.getConnection()方法获取一个连接来用。

所以spring中可以确保事务管理器中的Connection和JdbcTemplate中操作db的Connection是同一个,这样才能确保spring可以控制事务。

所以说,要想事务被回滚,必须让事务识别到异常,那个地方开启了事务,那个地方则需要识别到异常,没识别到则不会回滚,对比看下情况1和情况2,此时是不是比较清晰

image-20240108113802796

image-20240108113842695

img

再看情况3和情况4

因为spring声明式事务是通过事务拦截器TransactionInterceptor拦截目标方法,来实现事务管理的功能的所以通过this.all去调用的方法不会经过事务拦截器,也就没有事务啦

要想让事务生效,则必须通过注入的方式去调用❗️❗️❗️❗️❗️

此时再看下情况3,是不是了解了情况三为啥没事务啦

image-20240108114341872

image-20240108120418725

再看情况4,为啥他会开启三个事务呢

image-20240108114354448

那是因为Spring事务中一共有7种传播行为,默认的则是REQUIRED****

📚7种传播行为

Propagation是个枚举,有7种值,如下:

事务传播行为类型说明
REQUIRED如果当前事务管理器中没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择,是默认的传播行为。
SUPPORTS支持当前事务,如果当前事务管理器中没有事务,就以非事务方式执行。
MANDATORY使用当前的事务,如果当前事务管理器中没有事务,就抛出异常。
REQUIRES_NEW新建事务,如果当前事务管理器中存在事务,把当前事务挂起,然后会新建一个事务。
NOT_SUPPORTED以非事务方式执行操作,如果当前事务管理器中存在事务,就把当前事务挂起。
NEVER以非事务方式执行,如果当前事务管理器中存在事务,则抛出异常。
NESTED如果当前事务管理器中存在事务,则在嵌套事务内执行;如果当前事务管理器中没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

img

所以调用all的时候由于test2中没有事务,all则会自己新建一个事务啦,for循环了三次,则会新建三个事务呀,大家是不是都看明白了呢

看懂了建议给小编评论区来一波666,哈哈哈,比较码字不容易呀,你的支持就是小编连载的动力,求三连求三连求三连🥹(❁´◡❁)(❁´◡❁)

🖊️最后总结

🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍

搞笑点赞

这篇关于求求你,别再乱用@Transactional了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/588357

相关文章

@Transactional 参数详解

@Transactional 注解在 Spring 框架中用于声明一个方法或类应该在事务中执行。事务是一种确保数据库操作要么全部成功,要么全部失败的机制,确保数据的一致性和完整性。以下是 @Transactional 注解的参数详解: propagation: 事务传播行为,指定事务的传播方式。常见的传播行为有: REQUIRED(默认值):如果当前存在事务,则加入该事务;如果当前没有事务,则

@Transactional注解分析

事务具备ACID特性,即原子性、一致性、隔离性和持久性。 @Transactional注解是用来指定接口、类或方法必须拥有事务语义的元数据。 @Transactional注解就代表支持事务管理,如果这个注解在类上,那么表示该注解对于所有该类中的public方法都生效;如果注解出现在方法上,则代表该注解仅对该方法有效,会覆盖先前从类层次继承下来的注解。 一般情况下不要将这个注解加到接口和抽象类上,

四、事务拓扑(Transactional Topolgoy)

1、问题的提出     怎样做到每个出错的tuple只被处理一次?这样才能统计所有发射出的tuple的数量。 2、简介 Storm 0.7.0引入了Transactional Topology, 它可以保证每个tuple”被且仅被处理一次”, 这样你就可以实现一种非常准确,非常可扩展,并且高度容错方式来实现计数类应用。跟DRPC类似, transactional topology

利用Spring Boot的@Transactional注解保障业务数据的一致性

在现代软件开发中,特别是在分布式系统和微服务架构中,确保数据的一致性是一项至关重要的任务。当应用程序需要处理多个数据库操作时,保证这些操作要么全部成功,要么全部失败(即所谓的原子性),以及确保这些操作不会干扰其他并发运行的操作(即隔离性),成为了软件工程师们面临的挑战之一。Spring框架,尤其是Spring Boot,提供了一系列工具来简化这个过程,其中之一就是@Transactional注解。

Spring框架七、Spring Transactional传播特性

一、事务的传播特性 事务的传播特性指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行? spring的事务传播行为一共有7种: 二、测试事务的传播特性 1、环境准备 application_context.xml <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframewo

Spring Boot 中 `@Transactional` 注解使用示例

@Transactional 注解在 Spring Boot 中用于管理事务。它确保在方法执行过程中,所有数据库操作要么全部成功,要么全部回滚,以维护数据的一致性。下面是一些使用 @Transactional 的示例: 1. 在服务层使用 @Transactional @Servicepublic class UserService {@Autowiredprivate UserReposi

@Transactional和@Async能一起用吗?

是的,@Transactional 和 @Async 可以一起使用,但在使用时需要注意一些细节和潜在的问题。下面我将详细解释它们之间的交互方式,以及在一起使用时需要注意的事项。 基本概念 @Transactional:用于声明方法或类中的所有方法在事务上下文中执行。它确保一组数据库操作要么全部成功,要么全部回滚,以保持数据的一致性。@Async:用于异步执行方法,即方法将在单独的线程中执行,而

@Transactional的使用大全与注意事项

什么时候用? 在某个接口内需要进行事务处理的。比如在一个方法中,先要修改a表,然后将修改记录存到b表。业务需要这一系列操作是原子性的。 什么时候不用? 加上事务会拖慢接口的响应速度,所以要慎重。 (1)接口是幂等的时候。比如我要从a表查询出数据,然后将数据新增或更新到b表。这本来就是幂等的,不用加事务。 (2)本来就是事务的情况,比如批量插入个list。【这块需要注意,数据库的批量插入本来就

@Transactional 注解使用场景详细说明包括(不生效的场景,事务回滚)

有意识的在涉及事务相关方法上加@Transactional注解,是个好习惯。不过,很多同学只是下意识地添加这个注解,一旦功能正常运行,很少有人会深入验证异常情况下事务是否能正确回滚。@Transactional 注解虽然用起来简单,但这货总是能在一些你意想不到的情况下失效,防不胜防! 我把这些事务问题归结成了三类:不必要、不生效、不回滚,接下用一些demo演示下各自的场景。 一:不必要 1、

工作 6 年,@Transactional 注解用的一塌糊涂

接手新项目一言难尽,别的不说单单就一个 @Transactional 注解用的一塌糊涂,五花八门的用法,很大部分还失效无法回滚。 有意识的在涉及事务相关方法上加@Transactional注解,是个好习惯。不过,很多同学只是下意识地添加这个注解,一旦功能正常运行,很少有人会深入验证异常情况下事务是否能正确回滚。@Transactional 注解虽然用起来简单,但这货总是能在一些你意想不到的情