SpringBoot 事务管理

事务

事务是对支持事务的关系型数据库中的数据操作的完整性和一致性。所有数据要么一起成功,要么一起失败。
事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操作都必须成功执行,只要有发生异常就回退到事务开始未进行操作的状态。

事务特性ACID

ACID指数据库事务正确执行的四个基本要素的缩写。
包含:

原子性(Atomicity)是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency) 事务前后数据的完整性必须保持一致。

隔离性(Isolation)是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

持久性(Durability)指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
SpringBoot 事务管理_第1张图片

事务的传播行为(7种)

PROPAGATION_REQUIRED
如果业务层已经准备好了一个事务,则数据层就不再开启新的事务。而继续使用已有的事务进行控制。如果没有开启,则开启新的事务控制。

事务的隔离级别(5种)

数据库的脏读、不可重复读、幻读,发生在多个Session并发事务导致的问题。
脏读:同时访问一条数据,事务A读取了事务B修改后但未提交的数据。当事务B执行回滚操作,则事务A使用的是无效的数据。
不可重复读:同一事务两次查询的结果不同,发生在事务B已经update的数据。
幻读:同一事务两次查询结果不同,发生在事务B进行Insert或delete。

isolation_default 数据库默认的事务隔离级别
isolation_read_uncommitted 事务最低的隔离级别
isolation_read_committted 使用当前事务,若不存在则抛出异常
isolation_repeatable_read 新建事务,若当前存在事务,就把当前事务挂起
isolation_serializable 以非事务方式执行操作,若当前存在事务,就把当前事务挂起

JDBC中的事务控制

JDBC中的事务控制,对于数据库的开发与控制只有JDBC提供标准,在JDBC之中所有的事务被Connection连接接口所管理。
Spring中充分考虑了事务控制的问题,所以将其与AOP的特征结合在一起,形成了新的事务处理机制:通过AspectJ表达式来实现事务控制的切面逻辑。

Spring提供事务管理API

Spring框架中涉及到事务管理的API有100个左右,其中最重要的有以下三个TransactionDefinition
PlatformTransactionManager、TransactionStatus

TransactionDefinition 事务定义

用于定义一个事务。它包含了事务的静态属性,比如:事务传播行为、隔离级别、超时时间等。

PlatformTransactionManager 平台事务管理器

用于执行具体的事务操作,方法列表如下:全部抛出TransactionException异常。

TransactionStatus

该接口可以让事务管理器控制事务的执行,可以检查事务:
是否一个新的事务
是否有保存点
事务是否已经提交

关系:PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.

Spring提供的内置事务管理器

Spring并不直接管理事务,而是提供了许多内置事务管理器实现,如:DataSourceTransactionManager、HibernateTransactionManager等。
DataSourceTransactionManager适用于JDBC和IBatis进行数据持久化操作,在定义时需要提供底层的数据源(java.sql.DataSource)作为其属性。

Spring使用@EnableTransactionManager开启声明式事务的支持。开启后Spring容器会自动扫描注解@Transactional下的方法和类。

SpringBoot中的事务

SpringBoot中已经默认对JPA、JDBC、Mybatis开启了事务,引入它们依赖时事务就默认开启了,所以在SpringBoot中无需显示开启使用@EnableTransactionManager。

@Transactional 开启事务流程

开启事务
1.创建数据库连接
2.autocommit = false
3.执行多个sql后
4.调用connection.commit()方法,如果失败则执行rollback()方法

多数据源下开启事务

多数据源下启动类关闭自动开启事务,只给secondDataSource配置事务管理器

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, MybatisAutoConfiguration.class})
@SpringBootApplication
public class RentApplication {
    public static void main(String[] args) {
        SpringApplication.run(RentApplication.class, args);
    }
}

DBSecondConfig.java

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = DBSecondConfig.PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class DBSecondConfig {
    static final String PACKAGE ="cn.wxtong.rent.dao.second";
    static final String MAPPER_LOCATION ="classpath:mapper/second/*.xml";
    @Autowired
    @Qualifier("second")
    private DataSource secondDataSource;

    @Bean
    @Primary
    public SqlSessionFactory secondSqlSessionFactory() throws Exception{
        SqlSessionFactoryBean secondBean = new SqlSessionFactoryBean();
        secondBean.setDataSource(secondDataSource);
        secondBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
        return secondBean.getObject();
    }

    @Bean
    public DataSourceTransactionManager secondDataSourceTransactionManager() throws Exception{
        return new DataSourceTransactionManager(secondDataSource);
    }
}

Service与ServiceImpl

使用注解 @Transactional 定义在方法上,执行失败后事务全部回滚。

@Service
public class RentOrderServiceImpl implements RentOrderService {

    @Transactional
    public boolean addRentOrder() throws Exception{
        rentOrderDao.addRentOrder(o);
        od.devId = 123456789; //当不满足10位使之发生错误,事务自动回滚
        rentOrderDao.updateRentOrder(o);
        return true;
    };
}

参考文档

Spring-事务原理解读
https://blog.51cto.com/netpeak/1895393

https://www.cnblogs.com/balfish/p/8298296.html
https://blog.csdn.net/fly910905/article/details/78684772

你可能感兴趣的:(SpringBoot,spring,boot)