Spring事务管理是Java开发中绕不开的坎儿,它就像银行的保险柜,保证你的数据操作要么全部成功,要么全部失败,不会出现钱取出来一半系统崩了这种尴尬局面。今天桥哥就带你捋捋Spring事务的几种实现方式,从原始社会到现代文明,让你彻底明白!
编程式事务管理:手动挡的乐趣
这就像手动挡汽车,所有操作都得你自己来。你需要在代码里明确地调用beginTransaction()
、commit()
、rollback()
等方法,来控制事务的开始、提交和回滚。虽然麻烦,但控制力强,适合对事务有精确控制的需求。
TransactionTemplate:半自动挡
TransactionTemplate
稍微高级一点,不用手动commit()
和rollback()
,Spring会帮你处理。你只需要定义好操作逻辑,剩下的交给Spring就好。
@Resource
public TransactionTemplate transactionTemplate;
@Resource
public DataSource dataSource;
private static JdbcTemplate jdbcTemplate;
private static final String INSERT_SQL = "insert into cc(id) values(?)";
private static final String COUNT_SQL = "select count(*) from cc";
@Test
public void TransactionTemplateTest(){
jdbcTemplate = new JdbcTemplate(dataSource);
transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
jdbcTemplate.update(INSERT_SQL, "33"); //如果这里报错,事务会自动回滚
}
});
int i = jdbcTemplate.queryForInt(COUNT_SQL);
System.out.println("表中记录总数:"+i);
}
代码解释:
我们先获取 JdbcTemplate
对象,这是Spring提供的数据库操作工具。设置事务隔离级别为 ISOLATION_READ_COMMITTED
,这表示一个事务只能看到其他事务已提交的数据。使用 transactionTemplate.execute()
方法执行数据库操作。在这个方法内部,Spring会自动开启事务,并在操作完成后提交或回滚事务。
PlatformTransactionManager:纯手动挡
这才是真正的手动挡,所有操作都得自己控制。你需要获取TransactionStatus
对象,然后手动调用commit()
或rollback()
方法。
@Resource
public PlatformTransactionManager transactionManager;
@Test
public void showTransaction(){
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus transaction = transactionManager.getTransaction(def);
jdbcTemplate = new JdbcTemplate(dataSource);
try {
jdbcTemplate.update(INSERT_SQL,"2");
jdbcTemplate.update(INSERT_SQL,"是否");//出现异常,因为字段为int类型,会报异常,自动回滚
transactionManager.commit(transaction);
}catch (Exception e){
e.printStackTrace();
transactionManager.rollback(transaction);
}
int i1 = jdbcTemplate.queryForInt(COUNT_SQL);
System.out.println("表中记录总数:"+i1);
}
代码解释:
我们先定义事务的隔离级别和传播行为。 通过 transactionManager.getTransaction()
方法获取TransactionStatus
对象。在 try-catch
块中执行数据库操作,并在操作完成后手动提交或回滚事务。
**温馨提示:**编程式事务管理比较繁琐,现在很少直接使用,但理解它的原理对理解其他事务管理方式很有帮助。
声明式事务管理:自动挡的时代
这就像自动挡汽车,你只需要告诉它你要去哪儿,它会自动帮你处理油门、刹车、换挡等操作。你只需要配置好事务规则,Spring会自动帮你管理事务。
基于Aspectj AOP配置事务
这是通过AOP的方式来实现事务管理。你需要配置一个tx:advice
,然后将它织入到你的service层方法中。
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="tx" expression="execution(* cn.sys.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="tx" />
</aop:config>
代码解释:
tx:advice
定义了事务的规则,例如传播行为、回滚规则等。aop:config
将tx:advice
织入到cn.sys.service
包下的所有方法中。
基于@Transactional 的声明式事务管理
这是最常用的事务管理方式,只需要在方法上添加@Transactional
注解即可。
@Transactional
public int saveRwHist(List list) {
return rwDao.saveRwHist(list);
}
代码解释:
@Transactional
注解告诉Spring,这个方法需要进行事务管理。Spring会自动开启事务,并在方法执行完成后提交或回滚事务。
总结
Spring事务管理就像汽车的变速箱,从手动挡到自动挡,越来越方便。@Transactional
注解是目前最常用的方式,简单易用。但是,了解其他几种方式的原理,有助于你更好地理解Spring事务管理的本质。