Spring事物管理
V哥官网:http://www.vgxit.com
本文对应视频教程:http://www.vgxit.com/course/23
1,概述
之前我们已经使用了Spring来整合JdbcTemplate和Mybatis。但是我们并没有配置事务,我们知道在互联网开发项目中,数据库事务的配置是非常重要的。那么接下来我们就要来学习Spring的事物管理。
2,Spring数据库事务管理器设计思路
在Spring中,数据库事务通过PlatformTransactionManager进行管理。然后,Spring再给我们提供了一个支持事务的模板TransactionTemplate。我们可以看看TransactionTemplate的源码,其中核心的就是execute方法:
private PlatformTransactionManager transactionManager;
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
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 | Error ex) {
// Transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
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;
}
}
从上面源码中,我们可以看到,对应的流程如下:
- 事务的创建,提交和回滚是通过PlatformTransactionManager接口完成的
- 当事务产生异常时会回滚事务,在默认的实现中所有的异常都会回滚。我们可以通过配置去修改在某些异常发生时不会滚事务
- 当没有异常的时候提交事务
3,事物配置:
<!--注入事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
4,编程式事物
编程式事务以代码的方式管理事物,换句话说,事物将由开发者通过自己的代码实现。这里需要使用一个事物定义接口:TransactionDefinition。
private static void testInsert() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-cfg.xml");
UserMapper userMapper = ctx.getBean(UserMapper.class);
//创建一个事物定义类
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
//获取事物的秒数对象,也就是我们的事物管理器
PlatformTransactionManager transactionManager = ctx.getBean(PlatformTransactionManager.class);
//获取事物的状态
TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
try {
User user = User.builder().name("猪八戒").gender((short) 1).age(500).nickName("八戒").build();
userMapper.add(user);
// int a = 1 / 0;
//手动提交事物
transactionManager.commit(transactionStatus);
} catch (Throwable throwable) {
throwable.printStackTrace();
//手动回滚事务
transactionManager.rollback(transactionStatus);
}
}