详解Spring Boot 事务的使用
作者:mrr 发布时间:2022-08-09 01:59:07
spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。
关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。
你可以在启动类中添加如下方法,Debug测试,就能知道自动注入的是 PlatformTransactionManager 接口的哪个实现类。
@EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication {
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager){
System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
return new Object();
}
public static void main(String[] args) {
SpringApplication.run(ProfiledemoApplication.class, args);
}
}
这些SpringBoot为我们自动做了,这些对我们并不透明,如果你项目做的比较大,添加的持久化依赖比较多,我们还是会选择人为的指定使用哪个事务管理器。
代码如下:
@EnableTransactionManagement
@SpringBootApplication
public class ProfiledemoApplication {
// 其中 dataSource 框架会自动为我们注入
@Bean
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public Object testBean(PlatformTransactionManager platformTransactionManager) {
System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
return new Object();
}
public static void main(String[] args) {
SpringApplication.run(ProfiledemoApplication.class, args);
}
}
在Spring容器中,我们手工注解@Bean 将被优先加载,框架不会重新实例化其他的 PlatformTransactionManager 实现类。
然后在Service中,被 @Transactional 注解的方法,将支持事务。如果注解在类上,则整个类的所有方法都默认支持事务。
对于同一个工程中存在多个事务管理器要怎么处理,请看下面的实例,具体说明请看代码中的注释。
@EnableTransactionManagement // 开启注解事务管理,等同于xml配置文件中的 <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication implements TransactionManagementConfigurer {
@Resource(name="txManager2")
private PlatformTransactionManager txManager2;
// 创建事务管理器1
@Bean(name = "txManager1")
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// 创建事务管理器2
@Bean(name = "txManager2")
public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
// 实现接口 TransactionManagementConfigurer 方法,其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理器
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager2;
}
public static void main(String[] args) {
SpringApplication.run(ProfiledemoApplication.class, args);
}
}
@Component
public class DevSendMessage implements SendMessage {
// 使用value具体指定使用哪个事务管理器
@Transactional(value="txManager1")
@Override
public void send() {
System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
send2();
}
// 在存在多个事务管理器的情况下,如果使用value具体指定
// 则默认使用方法 annotationDrivenTransactionManager() 返回的事务管理器
@Transactional
public void send2() {
System.out.println(">>>>>>>>Dev Send2()<<<<<<<<");
}
}
注:
如果Spring容器中存在多个 PlatformTransactionManager 实例,并且没有实现接口 TransactionManagementConfigurer 指定默认值,在我们在方法上使用注解 @Transactional 的时候,就必须要用value指定,如果不指定,则会抛出异常。
对于系统需要提供默认事务管理的情况下,实现接口 TransactionManagementConfigurer 指定。
对有的系统,为了避免不必要的问题,在业务中必须要明确指定 @Transactional 的 value 值的情况下。不建议实现接口 TransactionManagementConfigurer,这样控制台会明确抛出异常,开发人员就不会忘记主动指定。
参考阅读:
详解SpringBoot的事务管理
Spring Boot 快速入门指南
Spring Boot 快速入门教程
以上所述是小编给大家介绍的Spring Boot 事务的使用网站的支持!


猜你喜欢
- SpringBoot 整合 Redis 数据库实现数据缓存的本质是整合 Redis 数据库,通过对需要“缓存&r
- 至少有K个重复字符的最长子串给你一个字符串 s 和一个整数 k ,请你找出 s 中的最长子串, 要求该子串中的每一字符出现次数都不
- 1. 传统方式:在内存中读取文件内容读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速
- BufferedInputStream BufferedInputStream 是缓冲输入流。它继承于FilterInputSt
- Java中多态性的实现什么是多态面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念
- 本文介绍了Flutter 通过Clipper实现各种自定义形状的示例代码,分享给大家,具体如下:ClipOval 圆形裁剪ClipOval(
- 目录一、自定义认证逻辑二、自定义过滤器总结一、自定义认证逻辑生成验证码工具<dependency> &
- 一、前言WPF没有内置IP地址输入控件,因此我们需要通过自己定义实现。我们先看一下IP地址输入控件有什么特性:输满三个数字焦点会往右移键盘←
- 问题使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据这是由于浏览器的同源策略导致的,目的是为了安全。在前后
- Spring与Hiberante整合通过hibernate的学习,我们知道,hibernate主要在hibernate.cfg.xml配置文
- package com.cooly;import java.util.LinkedList;/*** @author coolyqq*模拟打
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 最近一直在对接接口,上游返回的都是 JSON 数据,我们需要将这些数据进行保存,我们可以解析成 Map 通过 key 的方式进行获取,然后
- 消息都是存放在一个消息队列中去,而消息循环线程就是围绕这个消息队列进入一个无限循环的,直到线程退出。如果队列中有消息,消息循环线程就会把它取
- 一个简单好理解的例子,复制过去就能用,能看到效果首先对功能的思考,他怎么去实现1.制定udp广播的端口(如果收发用同一个端口就会一直接收到自
- 前言之前我们探讨过一个.class文件是如何被加载到jvm中的。但是jvm内又是如何划分内存的呢?这个内被加载到了那一块内存中?jvm内存划
- 本文实例讲述了C#实现xml文件反序列化读入数据到object的方法。分享给大家供大家参考。具体实现方法如下:public static o
- 前言注解是Java很强大的部分,但大多数时候我们倾向于使用而不是去创建注解。例如,在Java源代码里不难找到Java编译器处理的@Overr
- 目录常见的实现方式效果图:完整代码布局代码常见的实现方式切图,做旋转动画自定义View,绘制效果gif图1、切图会增加体积,但相对简单,不过
- 本文介绍了Android定时器Timer的停止和重启实现代码,分享给大家,具体如下:7月份做了一个项目,利用自定义控件呈现一幅动画,当时使用