事务的传播

事务的传播经常用到的是这两种

@Component
public class UserService {

	@Autowired
	private UserService userService;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
 	@Transactional
	public void test(){
//		TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
//			@Override
//			public void suspend() {
//				System.out.println("test对应的事务挂起");
//			}
//
//			@Override
//			public void resume() {
//				System.out.println("test对应的事务恢复");
//			}
//
//			@Override
//			public void beforeCommit(boolean readOnly) {
//				System.out.println("test对应的事务,在事务提交之前(在“完成之前”)调用");
//			}
//
//			@Override
//			public void beforeCompletion() {
//				System.out.println("test对应的事务,在事务提交/回滚之前调用。可以在事务完成之前执行资源清理。");
//			}
//
//			@Override
//			public void afterCommit() {
//				System.out.println("test对应的事务,在事务提交后调用。在主事务成功提交后,可以立即执行进一步的操作。成功提交后应执行的进一步操作,如确认消息或电子邮件。");
//			}
//
//			@Override
//			public void afterCompletion(int status) {
//				System.out.println("test对应的事务,在事务提交/回滚后调用。可以在事务完成后执行资源清理。");
//			}
//		});
		jdbcTemplate.execute("insert into user ('1','张三','男')");
		jdbcTemplate.execute("insert into user ('2','李四','男')");
		try {
			userService.a();
		}catch (Exception e){
			
		}
		jdbcTemplate.execute("insert into user ('4','李四1','男')");
	}

//	@Transactional
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void a(){
		jdbcTemplate.execute("insert into user ('3','王五','女')");
		throw new NullPointerException();
	}
}

@Transactional(propagation = Propagation.REQUIRES_NEW)这种事务传播,具体执行流程图

在这里插入图片描述
这种事务的传播时,a中抛异常,a事务回滚,test事务不受影响,照样提交。
而a与test都是@Transactional这个的时候,就说明a并未开启新的事务,还是用的test的事务,这时候,如果事务管理器并未设置部分异常全局回滚为false时,默认是true

transactionManager.setGlobalRollbackOnParticipationFailure(false);

两个方法的sql都会回滚。

另外一点,就是下面这种情况,因为将异常try了,所以事务还是会提交的,但是按理说应该不能提交

	@Transactional
	public void test(){
		jdbcTemplate.execute("insert into user ('2','李四','男')");
		try {
			throw new NullPointerException();
		}catch (Exception e){
			return 返回给前端比较友好的对象(处理后的对象)
		}
	}

所以这种情况,在commit方法中会有一个判断
`

	if (defStatus.isLocalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Transactional code has requested rollback");
			}
			processRollback(defStatus, false);
			return;
		}

就在catch 中加一个强制回滚,就可以回滚了

@Transactional
	public void test(){
		jdbcTemplate.execute("insert into user ('2','李四','男')");
		try {
			throw new NullPointerException();
		}catch (Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return 返回给前端比较友好的对象(处理后的对象)
		}
	}

mysql中的savepoint:(前面执行3个sql,创建savepoint,在执行2个sql,然后报错,这是回滚就只回滚到savepoint的位置,也就是后2条sql回滚,前面3个sql不回滚)

if (status.hasSavepoint()) {
	if (status.isDebug()) {
		logger.debug("Rolling back transaction to savepoint");
	}
	//回滚到上一个savepoint位置
	status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
	if (status.isDebug()) {
		logger.debug("Initiating transaction rollback");
	}
	//如果当前执行的方法是新开了一个事务,那么就直接回滚
	doRollback(status);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值