SpringBoot之事务处理机制

原创 2017年12月18日 17:32:15

一、Spring的事务机制

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

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

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

@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


控制台:


数据库:


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


控制台:


数据库:



参考资料《JavaEE开发的颠覆者 Spring Boot》

新手一枚,欢迎拍砖~ ~ ~













































                
版权声明:本文为博主原创文章,未经博主允许不得转载。

Spring Boot 事务的使用

Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactio...
  • catoop
  • catoop
  • 2016年01月27日 17:26
  • 91028

SpringBoot事务注解详解

关系型数据库多用到事务,在传统项目中使用xml配置,配置虽然也还好,但是看着很不美观,在使用SpringBoot框架,就简单的多了,以实战为准,直接上代码 @Transactionalspring 事...
  • Message_lx
  • Message_lx
  • 2017年08月25日 18:00
  • 731

SpringBoot入门系列:第六篇 mybatis

这一篇,代码折腾的时间较长,完成之后都是一些小细节,主要有三: 1、引入的依赖错误; 2、启动配置错误; 3、xml文件的mapper命名空间错误。 一、完整的pom.xml ...
  • lxhjh
  • lxhjh
  • 2016年06月26日 22:06
  • 14739

spring 编程式事务管理—PlatformTransactionManager

JDBC的事务管理在Spring2.0下有两种编程式的实现 PlatformTransactionManager TransactionTemplate 对于PlatformTranscti...
  • t1993ing
  • t1993ing
  • 2016年12月26日 15:08
  • 791

SpringBoot事务管理:声明式事务和编程式事务。将Service层的事务执行结果传递出去

在SpringBoot中使用事务很简单,这一篇不是为了讲事务,主要是讲一下一个工具类,将需要加入事务的Service层代码作为参数传递出去并返回事务的执行结果(成功和回滚)。 声明式事务 在Sprin...
  • tianyaleixiaowu
  • tianyaleixiaowu
  • 2017年06月12日 16:50
  • 6132

springboot springjpa 支持多个数据源

1.SpringBoot的程序启动类 import org.springframework.boot.SpringApplication; import org.springframework.boo...
  • ba5189tsl
  • ba5189tsl
  • 2015年08月07日 16:42
  • 17751

Spring事物管理器TransactionManager解析

Spring框架支持事务管理的核心是事务管理器抽象,对于不同的数据访问框架(如Hibernate)通过实现策略接口PlatformTransactionManager,从而能支持各种数据访问框架的事务...
  • wtopps
  • wtopps
  • 2015年04月27日 09:15
  • 8343

深入理解 Spring 之 SpringBoot 事务原理

前言今天是平安夜,先祝大家平安夜快乐。我们之前的数十篇文章分析了 Spring 和 Mybatis 的原理,基本上从源码层面都了解了他们的基本原理,那么。在我们日常使用这些框架的时候,还有哪些疑问呢?...
  • qq_38182963
  • qq_38182963
  • 2017年12月25日 11:48
  • 368

基于spring boot项目的多数据源配置与分布式事务处理总结

多数据源配置 项目存在10个数据源,如下 core_biz 业务逻辑 数据库core_sys 系统设置 数据库fund_pool 资金池 数据库 分用户拆分了8个库 针对这10个数据...
  • he90227
  • he90227
  • 2016年09月10日 10:53
  • 8311

SpringBoot-Mybatis处理事务

  • 2017年08月15日 21:52
  • 48.08MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SpringBoot之事务处理机制
举报原因:
原因补充:

(最多只允许输入30个字)