springboot中的事务

653 阅读3分钟

1、开启事务:在启动类中添加注解:@EnableTransactionManagement

2、通常在业务实现类中的方法上添加注解:@Transactional(rollbackFor = Exception.class)

3、手动开启注解: ①:自动注入两个been对象: @Autowired private DataSourceTransactionManager transactionManager;

	@Autowired
	private TransactionDefinition transactionDefinition;

②:获得事务状态: TransactionStatus transactionStatus = null; transactionStatus = transactionManager.getTransaction(transactionDefinition); 执行sql语句 提交事务:transactionManager.commit(transactionStatus); ③:如果发生一些特定异常需要通过sql语句将原数据还原(可以先记录原数据的一些标志,用于做为还原的条件), 如果是一些普通的异常,通常在提交事务后,可以定义一个变量(如:isCommit=false),如果没有出现异常,将 isCommit改为true,如果在后续的代码中出现了异常,在catch中通过判断这个字段为true,说明已经执行了sql, 可以通过:transactionManager.rollback(transactionStatus);来回滚事务,实例: catch(....) { if (!isCommit) { transactionManager.rollback(transactionStatus); }
}

4、事务的传播特性 ①:Propagation.NEVER 以非事务方式执行操作,如果当前事务存在则抛出异常。

@Transactional @Override public People insert(People people) { peopleDao.insert(people); // updatePeople(1); // 如果这样写,是没有起到spring事务传播的特性,无论是什么的传播特性,都没有生效(相当于updatePeople的注解没有生效),不会报错,是跟spring中的aop有关 peopleServiceImpl.updatePeople(1); // 如果这样写,通过spring的注册bean,传播特性为:NEVER,那么将会报错,并且数据回滚了(传播特性生效) 代理对象执行的方法

return null;

}

@Transactional(propagation = Propagation.NEVER) public void updatePeople(int id) {

}

报错:org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'

②:Propagation.REQUEST_NEW 新建事务,如果当前存在事务,把当前事务挂起。

第一种示例:

@Transactional insert 回滚,updatePeople不回滚 @Override public People insert(People people) { peopleDao.insert(people); peopleServiceImpl.updatePeople(1); // 回滚,新创建了一个数据库连接 throw new NullPointerException(); }

@Transactional(propagation = Propagation.REQUIRES_NEW) // 生效 public void updatePeople(int id) { People people = new People(); people.setId(1); people.setName("update"); peopleDao.update(people); // 不会回滚,插入到表中,因为新开了一个事务 }

第二种示例:insert 回滚,updatePeople回滚

@Transactional @Override public People insert(People people) { peopleDao.insert(people); // 回滚 updatePeople(1); // 没有创建新的的数据库连接 throw new NullPointerException(); }

@Transactional(propagation = Propagation.REQUIRES_NEW) // 失效 public void updatePeople(int id) { People people = new People(); people.setId(1); people.setName("update"); peopleDao.update(people); // 回滚 }

第三种示例 全部回滚

@Transactional @Override public People insert(People people) { peopleDao.insert(people); peopleServiceImpl.updatePeople(1); // 回滚 return null; }

@Transactional(propagation = Propagation.REQUIRES_NEW) // 失效 public void updatePeople(int id) { People people = new People(); people.setId(1); people.setName("update"); peopleDao.update(people); // 回滚 throw new NullPointerException(); }

③:Propagation.NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

第一种示例:

@Transactional @Override public People insert(People people) { peopleDao.insert(people); // 回滚 peopleServiceImpl.updatePeople(1); throw new NullPointerException(); }

@Transactional(propagation = Propagation.NOT_SUPPORTED) public void updatePeople(int id) { People people = new People(); people.setId(1); people.setName("update"); peopleDao.update(people); // 不会滚

}

第二种示例:

@Transactional @Override public People insert(People people) { peopleDao.insert(people); // 回滚 peopleServiceImpl.updatePeople(1); return null; }

@Transactional(propagation = Propagation.NOT_SUPPORTED) public void updatePeople(int id) { People people = new People(); people.setId(1); people.setName("update"); peopleDao.update(people); // 不会滚 throw new NullPointerException(); }

④:PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。 ⑤:PROPAGATION_SUPPORTS 支持当前事务,如果没有当前事务,就以非事务方法执行。 ⑥:PROPAGATION_MANDATORY 使用当前事务,如果没有当前事务,就抛出异常。 ⑦:PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED 类似的操作

5、事务失效场景 ①:采用的数据库引擎本身不支持事务 ②:事务管理的方法不是public修饰 ③:自身类没有被spring管理 ④:一个非@Transaction注解修饰的方法,调用一个@Transaction修饰的方法 ⑤:数据源没有配置事务管理器 ⑥:事务管理的方法,有try...catch捕捉 ⑦:事务管理的方法在try...catch捕捉后,抛出一个非RuntimeException异常。因为事务管理默认的异常时RuntimeException异常。如果想要抛出exception异常,可以在@Transaction中的属性 执行异常类型。 @Transactional(rollbackFor = Exception.class)

参考:www.cnblogs.com/javastack/p…