一篇文章搞定SpringBoot事务

SpringBoot框架提供的事务管理功能极大地简化了事务处理,使得开发者能够更加专注于业务逻辑的实现,而不是事务处理的细节。支持两种事务管理方式:编程式事务管理和声明式事务管理

一,事务管理器

SpringBoot使用事务管理器来管理事务。顶级接口为PlatformTransactionManager,常用实现类有 DataSourceTransactionManager(用于 JDBC 数据源的事务管理)和 JtaTransactionManager(用于分布式事务管理)

二,事务的属性

1.事务传播行为(Transaction Propagation)

事务传播行为定义了在一个事务方法被调用时,如何管理事务。常见的传播行为如下:

传播行为描述
REQUIRED支持当前事务,如果不存在就新建一个
SUPPORTS支持当前事务,如果当前没有事务,就以非事务的方式执行
MANDATORY必须运行在一个事务中,如果当前没有事务正在发生,将抛出一个异常
REQUIRES_NEW开启一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起
NOT_SUPPORTED以非事务方式运行,如果有事务存在,挂起当前事务
NEVER以非事务方式运行,如果有事务存在,抛出异常
NESTED如果当前正有一个事务在进行中,则该方法应当运行在一个嵌入式事务中。被套嵌的事务可以独立于外层事务进行提交和回滚。如果外层事务不存在,行为就像REQUIRE一样

2.事务的隔离级别(Transaction Isolation)

事务隔离级别定义了事务之间的隔离程度,以防止并发事务之间的干扰。常见的隔离级别如下:

隔离级别描述
DEFAULT默认,与数据库保持一致
READ_UNCOMMITTED可能会出现脏读、不可重复读、幻读
READ_COMMITTED可能会出现不可重复、幻读
REPEATABLE_READ (MySQL默认级别)可能会出现幻读
SERIALIZABLE不会出现并发事务的三大问题

3.事务超时(Transaction Timeout)

事务超时是指事务在指定时间内未能完成时会被自动回滚。默认情况下,事务没有超时限制
注意:最后一条DML语句之后的代码执行时间不被计入超时时间

4. 只读事务(Read-Only Transaction)

事务执行过程中只允许DQL语句执行,DML语句均不可执行。设置为true可启动Spring优化策略,提高SQL语句执行效率

5.事务回滚

指定哪些异常需要触发事务回滚

三,声明式事务管理

声明式事务管理则是通过配置来管理事务,开发者可以通过注解或XML配置来定义事务的边界和属性,而无需在代码中显式地编写事务管理的代码。这种方式大大减少了代码量,提高了可维护性。下面介绍@Transactional注解实现事务

1.@Transactional注解

@Transactional是Spring提供的主要注解,用于标识一个方法或类需要事务管理

属性说明
propagation事务的传播行为,默认值为PROPAGATION_REQUIRED
isolation事务的隔离级别,默认值为ISOLATION_DEFAULT
timeout事务的超时时间默认值为-1,表示永不超时
readOnly是否只读事务,默认值为false
rollbackFor指定哪些异常需要触发事务回滚
noRollbackFor指定哪些异常不触发事务回滚
transactionManager用于指定使用的事务管理器,""表示使用默认的事务管理器

2.代码实现

下列save方法可保证 saveA和saveB()两个DML操作同成功同失败

	@Transactional(rollbackFor = Exception.class)
    public void save() {
        saveA();// 数据库操作
        saveB();// 数据库操作
    }

3.Spring事务常见失效场景

(1)@Transactional定义的方法访问修饰符不是public
(2)@Transactional定义的类没有被Spring容器管理
(3)业务代码中异常被捕获但未抛出
(4)同一类内的方法直接调用(可使用自注入,使用bean调用方法解决失效)
(5)没有配置事务管理器
(6)事务传播性配置错误
(7)rollbackFor属性配置不当
(8)数据库不支持事务
(9)创建新线程并在新线程中执行数据库操作

四,编程式事务管理

编程式事务管理允许开发者通过编程的方式来控制事务的边界,即何时开始事务、何时提交事务或回滚事务。这种方式提供了极大的灵活性,但同时也增加了代码的复杂度

1.核心接口和类如下:

核心接口作用
PlatformTranscationManagerSpring事务管理的核心接口,提供了获取事务、提交事务和回滚事务的方法
DataSourceTransactionManagerPlatformTranscationManager的实现类,用于 JDBC 数据源的事务管理
JtaTransactionManagerPlatformTranscationManager的实现类,用于分布式事务管理
TransactionDefinition定义了事务的各种属性,如传播行为、隔离级别、超时值等
TransactionStatus表示事务的状态,包含了事务是否已开始、是否已标记回滚等信息

2.多线程事务控制代码实现

下列saveAll方法可以使所有线程中saveDemo()方法同成功同失败

@Service
public class DemoService {
	@Autowired
	ThreadPoolTaskExecutor threadPool;
	
    @Autowired
    DataSourceTransactionManager dsTxManager;
	
	public void saveAll(List<Demo> demos) {
		final CountDownLatch latch = new CountDownLatch(demos.size());
        AtomicBoolean isRollBack = new AtomicBoolean(false);
        for (Demo demo : demos) {
        	execute(demo, latch, isRollBack);
        }
	}
	
	public void execute(Demo demo, CountDownLatch latch, AtomicBoolean isRollBack) {
		threadPool.execute(() -> {
			// 开启事务
            TransactionStatus txStatus = dsTxManager.getTransaction(new DefaultTransactionDefinition());
            try {
            	// 数据库操作
                saveDemo(demo);
            } catch (Exception e) {
            	// 某个线程发生异常则将回滚标志置为true
                isRollBack.set(true);
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
            // 所有线程都会阻塞等待,直至latch值为0
            latch.await();
            if (isRollBack.get()) {
               	// 事务回滚
                dsTxManager.rollback(txStatus);
            } else {
            	// 事务提交
                dsTxManager.commit(txStatus);
            }
        });
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码届艺术家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值