欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈SpringBoot之事务处理机制

程序员文章站 2024-02-12 00:02:04
一、spring的事务机制 所有的数据访问技术都有事务处理机制,这些技术提供了api用来开启事务、提交事务来完成数据操作,或者在发生错误的时候回滚数据。 而spri...

一、spring的事务机制

所有的数据访问技术都有事务处理机制,这些技术提供了api用来开启事务、提交事务来完成数据操作,或者在发生错误的时候回滚数据。

而spring的事务机制是用统一的机制来处理不同数据访问技术的事务处理。spring的事务机制提供了一个platformtransactionmanager接口,不同的数据访问技术的事务使用不同的接口实现:

浅谈SpringBoot之事务处理机制

在程序中定义事务管理器的代码如下:

@bean 
public platformtransactionmanager transactionmanager() { 
 jpatransactionmanager transactionmanager = new jpatransactionmanager(); 
 transactionmanager.setdatasource(datasource()); 
 return transactionmanager; 
} 

二、声明式事务

spring支持声明式事务,即使用注解来选择需要使用事务的方法,它使用@transactional注解在方法上表明该方法需要事务支持。

@transactional 
public void savesomething(long id, string name) { 
 //数据库操作 
} 

在此处需要特别注意的是,此@transactional注解来自org.springframework.transaction.annotation包,而不是javax.transaction。

spring提供了一个@enabletransactionmanagement注解在配置类上来开启声明式事务的支持。使用了@enabletransactionmanagement后,spring容器会自动扫描注解@transactional的方法和类。@enabletransactionmanagement的使用方式如下:

@configuration 
@enabletransactionmanagement 
public class appconfig { 
 
} 

三、类级别使用@transactional

@transactional不仅可以注解在方法上,也可以注解在类上。当注解在类上的时候意味着此类的所有public方法都是开启事务的。如果类级别和方法级别同时使用了@transactional注解,则使用在类级别的注解会重载方法级别的注解。

四、spring data jpa的事务支持

spring data jpa对所有的默认方法都开启了事务支持,且查询类事务默认启用readonly=true属性。

这个从源码simplejparepository中可以看出,simplejparepository在类级别定义了@transactional(readonly=true),而在和save、delete相关的操作重写了@transactional属性,此时readonly属性是false,其余查询操作readonly仍然为false。

五、spring boot的事务支持

1.自动配置的事务管理器

在使用jdbc作为数据访问技术的时候,springboot为我们定义了platformtransactionmanager的实现datasourcetransactionmanager的bean;配置见org.springframework.boot.autoconfigure.jdbc.datasourcetransactionmanagerautoconfiguration类中的定义:

@bean 
@conditionalonmissingbean 
@conditionalonbean(datasource.class) 
public platformtransactionmanager transactionmanager() { 
 return new datasourcetransactionmanager(this.datasource); 
} 

在使用jpa作为数据访问技术的时候,spring boot为我们了定义一个platformtransactionmanager的实现jpatransactionmanager的bean;配置见org.springframework.boot.autoconfigure.orm.jpa.jpabaseconfiguration.class类中的定义:

@bean 
@conditionalonmissingbean(platformtransactionmanager.class) 
public platformtransactionmanager transactionmanager() { 
 return new jpatransactionmanager(); 
} 

2.自动开启注解事务的支持

spring boot专门用于配置事务的类为:org.springframework.boot.autoconfigure.transaction.transactionautoconfiguration,此配置类依赖于jpabaseconfiguration和datasourcetransactionmanagerautoconfiguration。

而在datasourcetransactionmanagerautoconfiguration配置里还开启了对声明式事务的支持,代码如下:

@conditionalonmissingbean(abstracttransactionmanagementconfiguration.class) 
@configuration 
@enabletransactionmanagement 
protected static class transactionmanagementconfiguration { 
 
} 

所以在spring boot中,无须显示开启使用@enabletransactionmanagement注解。

六、实例(springboot)

1.pom.xml:

<dependency> 
 <groupid>org.springframework.boot</groupid> 
 <artifactid>spring-boot-starter-web</artifactid> 
</dependency> 
<dependency> 
 <groupid>org.springframework.boot</groupid> 
 <artifactid>spring-boot-starter-data-jpa</artifactid> 
</dependency> 
<dependency> 
 <groupid>org.springframework.boot</groupid> 
 <artifactid>spring-boot-starter-data-rest</artifactid> 
</dependency> 
<dependency> 
 <groupid>mysql</groupid> 
 <artifactid>mysql-connector-java</artifactid> 
 <scope>runtime</scope> 
</dependency> 

2.application.yml:

server: 
 port: 5000 
 
spring: 
 datasource: 
 driver-class-name: com.mysql.jdbc.driver 
 url: jdbc:mysql://localhost:3306/test?useunicode=true&characterencoding=utf8&charactersetresults=utf8 
 username: root 
 password: password 
 
 jpa: 
 hibernate: 
 ddl-auto: update # 第一次简表create 后面用update 
 show-sql: true 

3.实体类staff:

@entity 
public class staff { 
 @id 
 @generatedvalue 
 private long id; 
 private string name; 
 private integer age; 
 private string address; 
 
 public staff() { 
 super(); 
 } 
 
 public staff(long id, string name, integer age, string address) { 
 super(); 
 this.id = id; 
 this.name = name; 
 this.age = age; 
 this.address = address; 
 } 
 //省略get、set方法 
} 

4.staff的repository:

public interface staffrepository extends jparepository<staff, long> { 
 
} 

5.服务接口:

public interface staffservice { 
 public staff savestaffwithrollback(staff staff);//回滚 
 public staff savestaffwithoutrollback(staff staff);//不回滚 
} 

6.服务实现:

@service 
public class staffserviceimpl implements staffservice { 
 
 @autowired 
 staffrepository staffrepository; //可以直接注入我们的rersonrepository的bean。 
 
 @override 
 //使用@transactional注解的rollbackfor属性,指定特定异常时,数据回滚。 
 @transactional(rollbackfor = {illegalargumentexception.class}) 
 public staff savestaffwithrollback(staff staff) { 
 staff s = staffrepository.save(staff); 
 if (staff.getname().equals("张三")) { 
  throw new illegalargumentexception("张三已经存在了,rollback"); 
 } 
 return s; 
 } 
 
 @override 
 public staff savestaffwithoutrollback(staff staff) { 
 staff s = staffrepository.save(staff); 
 if (staff.getname().equals("张三")) { 
  throw new illegalargumentexception("张三已经存在了,数据不回滚"); 
 } 
 return s; 
 } 
} 

7.controller:

@restcontroller 
@requestmapping("/staff") 
public class staffcontroller { 
 @autowired 
 staffservice staffservice; 
 
 //测试回滚情况 
 @requestmapping("/rollback") 
 public staff rollback(staff staff) { 
 return staffservice.savestaffwithrollback(staff); 
 } 
 
 //测试不回滚情况 
 @requestmapping("/notrollback") 
 public staff norollback(staff staff) { 
 return staffservice.savestaffwithoutrollback(staff); 
 } 
} 

8.运行测试:

(1)回滚:http://localhost:5000/staff/rollback?name=张三&age=18

浅谈SpringBoot之事务处理机制

控制台:

浅谈SpringBoot之事务处理机制

数据库:

浅谈SpringBoot之事务处理机制

(2)不回滚:http://localhost:5000/staff/notrollback?name=张三&age=18

浅谈SpringBoot之事务处理机制

控制台:

浅谈SpringBoot之事务处理机制

数据库:

浅谈SpringBoot之事务处理机制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。