浅析Spring 事务(二十一) spring事务的传播行为

经过我们上面一个章节的初步了解,我们已经知道了Spring事务的基本配置,今天我们一起接着讨论一下spring事务的传播


Spring是用枚举来表示事务传播行为的,

package org.springframework.transaction.annotation;

import org.springframework.transaction.TransactionDefinition;


public enum Propagation {

	
	REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),

	
	SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),

	
	MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),

	
	REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),


	PPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),

	
	NEVER(TransactionDefinition.PROPAGATION_NEVER),

	
	NESTED(TransactionDefinition.PROPAGATION_NESTED);


	private final int value;


	Propagation(int value) { this.value = value; }

	public int value() { return this.value; }

}
Propagation.REQUIRED代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建事务,
Propagation.SUPPORTS代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则该方法在非事务的上下文中执行
Propagation.MANDATORY代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则抛出异常
Propagation.REQUIRES_NEW创建一个新的事务上下文,如果当前方法的调用者已经有了事务,则挂起调用者的事务,这两个事务不处于同一上下文,如果各自发生异常,各自回滚
Propagation.NOT_SUPPORTED该方法以非事务的状态执行,如果调用该方法的调用者有事务则先挂起调用者的事务
Propagation.NEVER该方法以非事务的状态执行,如果调用者存在事务,则抛出异常
Propagation.NESTED如果当前上下文中存在事务,则以嵌套事务执行该方法,也就说,这部分方法是外部方法的一部分,调用者回滚,则该方法回滚,但如果该方法自己发生异常,则自己回滚,不会影响外部事务,如果不存在事务,则与PROPAGATION_REQUIRED一样,(其实这是数据库带有保存点的事务的典型体现,举例来说:旅游行业来说,游客从上海飞巴厘岛,需要从香港进行转机,那么上海~香港就是一个方法且是一个事务,香港~巴厘岛就是嵌入的方法,如果香港~巴厘岛航班取消了,无需回滚上海~香港的,这样代价太大,因为游客已经到了香港,只需修改香港到巴厘岛的航班就可以了,如果上海~香港的飞机取消了,则需要全部事务回滚,其实香港到巴厘岛的航班没有问题)
  


好了,介绍了基本概念,我们还是实战一下spring的传播行为吧

我们接着上篇博客的业务场景:

需求①:保存用户基本信息即可,如果保存用户的详细信息发生异常不需要全部回滚,我们修改代码


UserDetailServiceImpl.java

UserServiceImpl.java

测试类:

package org.study.spring.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.study.spring.transaction.entity.Profession;
import org.study.spring.transaction.entity.User;
import org.study.spring.transaction.entity.UserDetail;
import org.study.spring.transaction.service.UserService;

public class SpringTransactionTest {
    
    @Test
    public void test1() throws IllegalAccessException{
         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-transaction.xml");
         UserService userBussinessServiceImpl = applicationContext.getBean("userServiceImpl",UserService.class);
         userBussinessServiceImpl.saveUserAllInfo(new User("Ted",26), new UserDetail("Ted@163.com", "重庆高级公寓", "重庆大学"), new Profession("war3解说","电子竞技"));
    }  

}

运行测试类,数据库的结果是:


说明我们的设置成功了


②保存用户详细信息的时候,必须是在事务的上下文中执行,否则保存用户详细信息失败


修改代码UserServiceImpl.java去掉事务

UserServiceImpl.java


运行测试类

失败了,提示没有检测到事务上下文


我们再看看数据库



我们可以看到用户详细信息没有保存成功,虽然我们在保存用户详细信息的时候,代码层面并没有发生任何异常,但依旧没有保存成功


③新来的实习生在写保存profession的模块时,没有分清出not_support和never的区别,实习生是用never去管理,他的业务逻辑是觉得保存职业信息应该与主业务逻辑无关

代码修改如下:

ProfessionServiceImpl.java


UserServiceImpl.java


运行测试类


提示当前方法不应该在有事务的上下文中执行


我们修改一下ProfessionServiceImpl

顺便我们修改一下测试类的测试数据

package org.study.spring.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.study.spring.transaction.entity.Profession;
import org.study.spring.transaction.entity.User;
import org.study.spring.transaction.entity.UserDetail;
import org.study.spring.transaction.service.UserService;

public class SpringTransactionTest {
    
    @Test
    public void test1() throws IllegalAccessException{
         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-transaction.xml");
         UserService userBussinessServiceImpl = applicationContext.getBean("userServiceImpl",UserService.class);
         userBussinessServiceImpl.saveUserAllInfo(new User("Miss",26), new UserDetail("Miss@163.com", "上海浦东区", "上海大学"), new Profession("LOL解说","电子竞技"));
    }  

}
运行测试类,显示成功,数据库信息:


这样就算正确的写法了


好了,其他的用法大家自己去尝试一下,根据自己真实的业务场景,spring的事务传播行为在开发中占据了很重要的地位~

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值