Spring-Boot-15-事务

Spring 事务

  1. 数据库事务是企业应用中最为重要的内容之一。
  2. 事务往往会涉及到注释@Transactional

1. Spring的数据管理器的设计

  1. 在Spring中数据库事务是通过PlatformTransactionManager进行管理的,而能够支持事务的是org.springframework.transaction.support.TransactionTemplate,它是Spring所提供的事务管理器的模板。
//事务管理器
private PlatformTransactionManager transactionManager;
......
@Override
public <T> T execute(TransactionCallback<T> action) throws TransactionException{
	// 使用自定义的事务管理器
	if(this.transactionManager instanceof CallbackPreferringPlatformTransactionManager){
		return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this,action);
	}else{//系统默认管理器
		//获取事务状态
		TransactionStatus status = this.transactionManager.getTransaction(this);
		T result;
		try{
			//回调接口方法
			result = action.doInTransaction(status);
		}catch(RuntimeException ex){
			//Transactional code threw application exception -> rollback
			//回滚异常方法
			rollbackOnException(status, ex);
			//抛出异常
			throw ex;
		}catch(Error ex){
			//Transactional code threw error -> rollback
			//回滚异常方法
			rollbackOnException(status, err);
			//抛出错误
			throw err;
		}catch(Throwable ex){
			//Transactional code threw unexpected exception -> rollback
			//回滚异常方法
			rollbackOnException(status, ex);
			//抛出无法捕获异常
			throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
		}
		//提交事务
		this.transactionManager.commit(status);
		//返回结果
		return result;
	}
}
  1. 事务的创建、提交和回滚是通过PlatformTransactionManager接口来完成。
  2. 当事务产生异常时会回滚事务,在默认的实现中所有的异常都会回滚,可以通过配置去修改在某些异常发生时回滚或者不会滚事务。
  3. 当无异常时,会提交事务。
  4. 多种事务管理器如下

1.1. 数据管理器分类

  1. 可以看到多个数据库管理器,并且支持JTA事务,常用的是DataSourceTransactionManager,集成抽象事务管理器AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager又实现了PlatformTransactionManager。这样Spring就可以如同源码中那样使用PlatformTransactionManager接口的方法,创建、提交或者回滚事务了。
  2. PlatformTransactionManager接口的源码如下:
public interface PlatformTransactionManager{
    //获取事务状态
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
    // 提交事务
    void commit(TransactionStatus status) throws TransactionException;
    //回滚事务
    void rollback(TransactionStatus status) throws TransactionException;
}

2. 通过标签来完成Spring的事务回滚

  1. 将所有的对于数据库的操作都放置到一个被@Transactional标记的Service方法中可以全部回滚
@Transactional
public boolean UserRegister(ESysUser entity) {
	try {
		//插入ESysUser
		eSysUserDao.insert(entity);
	} catch (Exception e) {
		// handle exception 启动回滚
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		log.error(e.getMessage(), e);
		return false;
	}
}

2.1. 根据异常进行回滚

@Transactional(rollbackFor = { Exception.class})

  1. 没有捕获异常,则会抛出异常,则将doDbStuff1()中的数据库操作进行回滚。
@Transactional(rollbackFor = { Exception.class })    
public void test() throws Exception {    
     doDbStuff1();    
     doDbStuff2();//假如这个操作数据库的方法会抛出异常,方法doDbStuff1()对数据库的操作会回滚。    
}  
  1. 如果在程序中自已捕获异常未往外抛,如下代码事务不会回滚
@Transactional(rollbackFor = { Exception.class })    
public void test() {    
     try {    
        doDbStuff1();    
        doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作  不会回滚。    
     } catch (Exception e) {    
           e.printStackTrace();       
     }    
}
  1. 既要捕获异常,又要回滚
@Transactional(rollbackFor = { Exception.class })    
public void test() {    
	try {    
		doDbStuff1();
		doDbStuff2();
	} catch (Exception e) {
		e.printStackTrace();
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常,
		return;  
  }    
}

2.2. 回滚部分异常

  1. 使用Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();设置回滚点。
  2. 使用TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);回滚到savePoint。
@Transactional(rollbackFor = Exception.class)
@Override
public void saveEntity() throws Exception{
    Object savePoint = null;
    try {
        userDao.saveUser();
        //设置回滚点
        savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        studentDao.saveStudent(); //执行成功
        int a = 10/0; //这里因为除数0会报异常,进入catch块
    }catch (Exception e){
        System.out.println("异常了=====" + e);
        //手工回滚异常
        TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
    }
}

3. 参考

  1. 【Java EE】深入Spring数据库事务管理
  2. spring事务回滚:当同时需要在多个数据表插入数据时,一个出错如何实现全部回滚
  3. Spring中抛出异常时,既要要返回错误信息,还要做事务回滚
  4. SpringBoot事务简单操作及手动回滚
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值