Spring的事务的传播属性

本文详细介绍了Spring的7种事务传播属性,包括PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS等,并通过示例说明了PROPAGATION_REQUIRED和PROPAGATION_REQUIRES_NEW的使用场景。在PROPAGATION_REQUIRED情况下,如果发生异常,外部事务会回滚,但内部事务会正常提交。而在PROPAGATION_REQUIRES_NEW中,无论内外部事务,异常只会导致内部事务回滚。分析了不同情况下,事务异常处理对内外部事务的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring事务有7种传播属性:
1.PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
2.PROPAGATION_SUPPORTS:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
3.PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
4.PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
5.PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED:支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

下面,我们以PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEW来写一个示例:

    @Transactional
	@Override
	public void addUser() {
		User user1 = new User();
		user1.setUserName("zhaoliu21");
		user1.setName("赵柳21");
		user1.setPassword("12323");
		user1.setSex(1);
		user1.setUserType(12);
		user1.setStatus(1);
		user1.setOrganizationId(12);
		userMapper.insert(user1);
		try {
			((UserService)AopContext.currentProxy()).updateUser(user1);
		}catch (Exception e) {
			System.out.println("ArithmeticException****************************");
			e.printStackTrace();
		}		
	}

    @Transactional(propagation=Propagation.REQUIRES_NEW)
	@Override
	public void updateUser(User user) {
		System.out.println("************updateUser  开始**************");
		User user1 = new User();
		user1.setId(46L);
		user1.setName("王武");
		userMapper.updateUserById(user1);
		System.out.println("************updateUser  结束**************");
		int a = 1/0;		
	}

当调用updateUser()时,会重新开启一个事务,由于程序执行1/0会报异常,要保证内部事务回滚,外部事务正常提交,那么就要在addUser()中调用updateUser()时进行try{}catch () {}处理。

    @Transactional
	@Override
	public void addUser() {
		User user1 = new User();
		user1.setUserName("zhaoliu21");
		user1.setName("赵柳21");
		user1.setPassword("12323");
		user1.setSex(1);
		user1.setUserType(12);
		user1.setStatus(1);
		user1.setOrganizationId(12);
		userMapper.insert(user1);
		((UserService)AopContext.currentProxy()).updateUser(user1);		
		int a = 1/0;
	}

    @Transactional(propagation=Propagation.REQUIRES_NEW)
	@Override
	public void updateUser(User user) {		
		System.out.println("************updateUser  开始**************");
		User user1 = new User();
		user1.setId(46L);
		user1.setName("王武");
		userMapper.updateUserById(user1);
		System.out.println("************updateUser  结束**************");
	}

如上代码,当addUser()程序异常时,外部事务回滚,内部事务会正常提交。


void methodA(){
	service.methodB();
}

void methodB(){

}

这里有A,B两个方法,在A方法中调用B方法。分如下两种情况:
一、运行的B方法出现异常
1.不做处理
新建事务:影响外部事务,影响自己
嵌套事务:影响外部事务,影响自己
共享事务:影响外部事务,影响自己

2.B方法抛出异常,由A方法内部处理
新建事务:不影响外部事务,影响自己
嵌套事务:不影响外部事务,影响自己
共享事务:影响外部事务,影响自己

3.B方法内部处理
不影响任何事务

4.两个方法都抛异常
等同不做处理

二、运行的A方法出现异常,B方法不出现异常
1.不做处理
新建事务:影响自己,不影响内部事务
嵌套事务:影响自己,影响内部事务
共享事务:影响自己,影响内部事务

2.A方法内部处理
新建事务:全部不影响
嵌套事务:全部不影响
共享事务:全部不影响

3.A方法抛异常
等同不做处理


腾讯云618大促腾讯云618钜惠
阿里云最高2000代金券阿里云新购、续费、升级优惠券

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值