@Transactional传播属性

required有则有无则创建(默认)

说明: 如果当前已经存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值。

@Service
public class RequireMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = Propagation.REQUIRED)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("Transaction1-----" + act);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void methodSon2() {
		User user = new User();
		user.setId(2);
		user.setUserName("B");
		userService.save(user);
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("Transaction2-----" + act);
	}

}
@Service
public class RequireService {

	@Autowired
	RequireMethodService requireMethodService;
	
	@Transactional
    public void service() {
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("begin-----" + act);
		requireMethodService.methodSon1();
		requireMethodService.methodSon2();
    } 
    
}

执行结果:事务是相同的

begin-----com.cn.service.propagation.require.RequireService.service
Transaction1-----com.cn.service.propagation.require.RequireService.service
Transaction2-----com.cn.service.propagation.require.RequireService.service

supports有则有无则无事务

如果当前已经存在事务,那么加入该事务,否则创建一个所谓的空事务(可以认为无事务执行)。

@Service
public class SupportMethodService {

	@Autowired
	UserService userService;

	/**
	 * 如果当前有事务则加入事务中,如果没有则什么都不做,相当于没事务。
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
		throw new RuntimeException("异常");
	}


}
@Service
public class SupportService {

	@Autowired
	SupportMethodService supportMethodService;
	
	/**
	 * @Transactional,开启事务后,service会和methodSon1公用一个事务,此时methodSon1会正常回滚;
	 * 
	 * 如果这里没有开启,则methodSon1不会自己创建事务。此时methodSon1会不会回滚,数据插入到数据库;
	 * 
	 */
	@Transactional
    public void service() {
		supportMethodService.methodSon1();
		
    } 
    
}

执行结果:
SupportService在调用SupportMethodService的过程中
1. SupportService没有事务,则methodSon1也没有事务,不会回滚,数据插入到数据库。
2. SupportService有事务,则methodSon1加入到事务中,会回滚。

mandatory必须有事务

当前必须存在一个事务,否则抛出异常。

@Service
public class MandatoryMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = Propagation.MANDATORY)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
	}

	@Transactional(propagation = Propagation.MANDATORY)
	public void methodSon2() {
		User user = new User();
		user.setId(2);
		user.setUserName("B");
		userService.save(user);
	}
	

}
@Service
public class MandatoryService {

	@Autowired
	MandatoryMethodService mandatoryMethodService;
	
	/**
	 * 当前必须存在一个事务,否则抛出异常。
	 * 
	 */
//	@Transactional
    public void service() {
		//没有事务
		mandatoryMethodService.methodSon1();
    } 
    
}

执行结果:

org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:362) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.6.jar:5.3.6]

never 必须没有事务

如果当前存在事务,则抛出异常

@Service
public class NeverMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = Propagation.REQUIRED)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
	}

	@Transactional(propagation = Propagation.NEVER)
	public void methodSon2() {
		User user = new User();
		user.setId(2);
		user.setUserName("B");
		userService.save(user);
	}
	

}
@Service
public class NeverService {

	@Autowired
	NeverMethodService neverMethodService;
	
	/**
	 * 如果当前存在事务,则抛出异常,否则在无事务环境上执行代码。
	 * 
	 * 如果调用方法上已经有事务,被调用方法上会报错。
	 */
	@Transactional
    public void service() {
		//methodSon1创建了事务,但不会影响methodSon2
    	neverMethodService.methodSon1();
    	//methodSon2此时会报错,因为service()上已经开启了事务
    	neverMethodService.methodSon2();
    } 
    
}

执行结果:

org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:413) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:352) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.6.jar:5.3.6]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.6.jar:5.3.6]

requires_new新事务

REQUIRES_NEW新建一个事务,不管当前有没有事务,都新建一个独立的事务。

@Service
public class RequireNewMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = Propagation.REQUIRED)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("Transaction1-----" + act);
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void methodSon2() {
		User user = new User();
		user.setId(2);
		user.setUserName("B");
		userService.save(user);
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("Transaction2-----" + act);
	}


}
@Service
public class RequireNewService {

	@Autowired
	RequireNewMethodService requireNewMethodService;
	
	/**
	 * REQUIRES_NEW新建一个事务,不管当前有没有事务,都新建一个独立的事务。
	 */
	@Transactional
    public void service() {
		String act = TransactionSynchronizationManager.getCurrentTransactionName();
		System.out.println("begin-----" + act);
		requireNewMethodService.methodSon1();
		
		requireNewMethodService.methodSon2();
    } 
    
}

执行结果:

begin-----com.cn.service.propagation.requiresnew.RequireNewService.service
Transaction1-----com.cn.service.propagation.requiresnew.RequireNewService.service
Transaction2-----com.cn.service.propagation.requiresnew.RequireNewMethodService.methodSon2

nested嵌套事务

1)methodSon2方法内部报错,则只会回滚methodSon2里面的。

2)methodSon2方法内部不报错,但是外面的调用方报错了,则methodSon2会跟着一起回滚。

3)methodSon2方法内部不报错,外面也不报错,则methodSon2和外面事务一起提交。

@Service
public class NestedMethodService {

	@Autowired
	UserService userService;

	@Transactional(propagation = Propagation.REQUIRED)
	public void methodSon1() {
		User user = new User();
		user.setId(1);
		user.setUserName("A");
		userService.save(user);
	}

	@Transactional(propagation = Propagation.NESTED)
	public void methodSon2() {
		User user = new User();
		user.setId(2);
		user.setUserName("B");
		userService.save(user);
		throw new RuntimeException("methodSon2异常");
	}


}

@Service
public class NestedService {

	@Autowired
	NestedMethodService nestedMethodService;
	
	/**
	 * methodSon2方法内部报错,则只会回滚methodSon2里面的。
	 */
	@Transactional
    public void service() {
		nestedMethodService.methodSon1();
		try {
			nestedMethodService.methodSon2();
        } catch (Exception e) {
            e.printStackTrace();
        }
    } 
	
	/**
	 * methodSon1方法内部不报错,但是外面的methodSon2报错了,则methodSon1会跟着一起回滚。
	 */
	@Transactional
    public void service2() {
		try {
			nestedMethodService.methodSon1();
        } catch (Exception e) {
            e.printStackTrace();
        }
		nestedMethodService.methodSon2();
    } 
	
	
    
}

总结:

在methodA()调用methodB()情况下

REQUIREDREQUIRES_NEWNESTED
如果methodB()抛出异常,在methodA()中没有try catch住A、B都回滚A、B都回滚A、B都回滚
如果methodB() 抛出异常,在methodA()中try catch住,没有重新抛出A、B都回滚A不回滚 B回滚A不回滚 B回滚
如果methodB() 抛出异常,在methodA()中try catch住,重新抛出A、B都回滚A、B都回滚A、B都回滚
如果只有methodA抛出异常(先执行B,后执行A)A、B都回滚A回滚 B不回滚A、B都回滚

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值