IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java--SpringBoot使用@Transactional注解添加事务 -> 正文阅读

[Java知识库]Java--SpringBoot使用@Transactional注解添加事务

一、Java事务

1、通常的观念认为,事务仅与数据库相关。

事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)一致性(consistency)、**隔离性 (isolation)和持久性(durability)**的缩写。

事务的原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。
事务的一致性:表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。
事务的隔离性:表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。
事务的持久性:表示已提交的数据在事务执行失败时,数据的状态都应该正确。

通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行

既然事务的概念从数据库而来,那Java事务是什么?之间有什么联系? 实际上,一个Java应用系统,如果要操作数据库,则通过JDBC来实现的。增加、修改、删除都是通过相应方法间接来实现的,事务的控制也相应转移到Java程序代码中。 因此,数据库操作的事务习惯上就称为Java事务。

2、为什么需要Java事务

事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。

举一个简单例子: 比如银行转帐业务,账户A要将自己账户上的1000元转到B账 户下面,A账户余额首先要减去1000元,然后B账户要增加1000元。假如在中间网络出现了问题,A账户减去1000元已经结束, B因为网络中断而操作 失败,那么整个业务失败,必须做出控制,要求A账户转帐业务撤销。这才能保证业务的正确性,完成这个操作就需要事务,将A账户资金减少和B账户资金增加方 到一个事务里面,要么全部执行成功,要么操作全部撤销,这样就保持了数据的安全性。

二、SpringBoot事务

在Spring中,事务有两种实现方式,分别是编程式事务管理和声明式事务管理两种方式。
1、编程式事务管理: 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
2、声明式事务管理: 建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务管理不需要入侵代码,通过@Transactional就可以进行事务操作,更快捷而且简单。推荐使用

在我们使用Springboot框架来开发时,Springboot已经帮我们封装好对底层数据库事务的操作(Springboot版本2.3.1.RELEASE,整合了mybatis,数据库使用MySQL),降低了我们学习、操作使用数据库事务的成本。

三、SpringBoot事务配置使用

1、依赖的Jar包**pom.xml**

Spring Boot中实现事务没有额外的Jar包,还是基本的数据库访问包,比如mybatis

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.13</version>
</dependency>

2、配置事务,使用注解@Transactional事务

在Mybatis中使用事务,非常简单,只需要在方法上增加注解@Transactional,无需任何配置

@Service
public class UserServiceImpl implements UserService
{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthService authService;

    /**
    * 更新user的权限,角色信息
    */
    @Override
    @Transactional
    public updateUser(User user){
        userMapper.updateUser(user);

        roleService.insertRoleUser(user);

        authService.updateAuthUser(user);
    }
}

@Transactional可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。因此可以在Service层和Controller层使用

虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

我看网上说还需要导入Spring boot提供的JDBC或JPA依赖,

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
   <scope>test</scope>
</dependency>
 
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
   <scope>test</scope>
</dependency>

在_@SpringBootApplication上添加注解@EnableTransactionManagement,如下:_

关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。

我们通过Debug测试,就能知道自动注入的是 PlatformTransactionManager 接口的哪个实现类

//网上说在springboot的启动中添加注解@EnableTransactionManagement
@SpringBootApplication
@EnableTransactionManagement //开启事务管理注解模式 最新的版本可以省略
@MapperScan("com.xz.springboot.mapper") //扫描该包下所有的接口并为该接口生成实现类
public class SpringbootApplication {

    @Bean
    public Object testBean(PlatformTransactionManager platformTransactionManager){
        System.out.println(">>>>>>>>>>" +         
        platformTransactionManager.getClass().getName());
        return new Object();
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }

}

注:

博主亲测,现在 版本Springboot确实不需要上述导入包和启动类添加@EnableTransactionManagement注解

传统工程中使用XML配置事务时,需要给DataSourceTransactionManager事务管理器配置数据源DataSource,那么Spring Boot进行自动配置的话,
Spring Boot在注入DataSourceTransactionManager事务管理器时,Spring Boot会自动到Spring容器中寻找我们配置好的DataSource。也即是之前我们的手动操作,现在使用Spring Boot变成了自动化操作。

四、事务注解详解

默认遇到throw new RuntimeException(“…”);会回滚
需要捕获的throw new Exception(“…”);不会回滚

指定回滚

@Transactional(rollbackFor=Exception.class) 
    public void methodName() {
       // 不会回滚
       throw new Exception("...");
    } 

指定不回滚

@Transactional(noRollbackFor=Exception.class)
    public ItimDaoImpl getItemDaoImpl() {
        // 会回滚
        throw new RuntimeException("注释");
    } 

如果有事务,那么加入事务,没有的话新建一个(不写的情况下)

@Transactional(propagation=Propagation.REQUIRED) 

容器不为这个方法开启事务

@Transactional(propagation=Propagation.NOT_SUPPORTED)

readOnly=true只读,不能更新,删除

@Transactional (propagation = Propagation.REQUIRED,readOnly=true) 

设置超时时间

@Transactional (propagation = Propagation.REQUIRED,timeout=30)

设置数据库隔离级别

@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)

五、事务注解 – @Transactional 使用注意事项

1、不要在接口上声明@Transactional,而要在具体类的方法上使用@Transactional注解,否则注解可能无效。

2、将@Transactional放置在类级的声明中放在类声明会使得所有方法都有事务故@Transactional应该放在方法级别不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。

3、使用了@Transactional的方法,对同一个类里面的方法调用,@Transactional无效。比如有一个类Test,它的一个方法A,A再调用Test本类的方法B(不管B是否public还是private),但A没有声明注解事务,而B有。则外部调用A之后,B的事务是不会起作用的。(经常在这里出错)

4、使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在protected、private或者package-visible的方法上使用@Transactional注解,它也不会报错,但事务无效。

5、经过在ICORE-CLAIM中测试,效果如下:

6、抛出受查异常XXXException,事务会回滚。

7、抛出运行时异常NullPointerException,事务会回滚。

8、Quartz中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)

9、异步任务中,execute直接调用加了@Transactional方法,可以回滚;间接调用,不会回滚。(即上文3点提到的)

10、在action中加上@Transactional,不会回滚。切记不要在action中加上事务。

11、在service中加上@Transactional,如果是action直接调该方法,会回滚,如果是间接调,不会回滚。(即上文3提到的)

12、在service中的private加上@Transactional,事务不会回滚。

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:29:56  更:2022-08-06 10:31:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:51:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码