前言
spring事务管理包含两种情况,编程式事务、声明式事务。而声明式事务又包括基于注解@Transactional和tx+aop的方式。那么本文先分析编程式注解事务和基于注解的声明式事务。 编程式事务管理使用TransactionTemplate或者PlatformTransactionManager。对于编程式事务spring推荐使用TransactionTemplate。
一、编程式事务
spring事务特性
spring中所有的事务策略类都继承自org.springframework.transaction.PlatformTransactionManager接口
public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; }
编程式事务TransactionTemplate需要手动在代码中处理事务,一般不推荐使用,也不符合spring的思想,因为它直接耦合代码,但各有利弊。先看下TransactionTemplate的源码。
public class TransactionTemplate extends DefaultTransactionDefinition implements TransactionOperations, InitializingBean { protected final Log logger = LogFactory.getLog(getClass()); private PlatformTransactionManager transactionManager; public TransactionTemplate() { } public TransactionTemplate(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) { super(transactionDefinition); this.transactionManager = transactionManager; } public void setTransactionManager(PlatformTransactionManager transactionManager) { this.transactionManager = transactionManager; } public PlatformTransactionManager getTransactionManager() { return this.transactionManager; } @Override public void afterPropertiesSet() { if (this.transactionManager == null) { throw new IllegalArgumentException("Property 'transactionManager' is required"); } } @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 err) { // 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; } } private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException { logger.debug("Initiating transaction rollback on application exception", ex); try { this.transactionManager.rollback(status); } catch (TransactionSystemException ex2) { logger.error("Application exception overridden by rollback exception", ex); ex2.initApplicationException(ex); throw ex2; } catch (RuntimeException ex2) { logger.error("Application exception overridden by rollback exception", ex); throw ex2; } catch (Error err) { logger.error("Application exception overridden by rollback error", ex); throw err; } } }
从上面的代码可以看到核心方法是execute,该方法入参TransactionCallback<T>。查看TransactionCallback源码:
public interface TransactionCallback<T> { T doInTransaction(TransactionStatus status); }
那么以上两个源码可以确定我们使用编程式事务管理的方式也就是自己需要重写doInTransaction()。OK,那么我们手动使用TransactionTemplate处理下。
1、先配置transactionmanager
<!--事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
2、配置transactionTemplate
<!--编程式事务,推荐使用TransactionTemplate--> <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean>
3、业务代码处理
@Autowired private TransactionTemplate transactionTemplate; public int insertUser2(final User user) { Integer i= (Integer) this.transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus transactionStatus) { int i = userMapper.insertUser(user); if (i > 0) { System.out.println("success"); } int j = 10 / 0; return i; } }); return i; }
业务代码中我们使用by zero的异常故意抛出,你会发现能继续打印success,当你断点debug时,你会发现数据库一直是锁定状态,直到你程序执行完。如下图:
二、基于Transactional注解的事务管理
当前应该是使用最清爽的事务管理方式了,也符合spring的理念,非入侵代码的方式。
1、配置
<!--事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 使用注解事务,需要添加Transactional注解属性 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--启用最新的注解器、映射器--> <mvc:annotation-driven/>
2、配置后只需要在要处理的地方加上Transactional注解,而且Transactional注解的方式可以应用在类上,也可以应用在方法上,当然只针对public方法。
3、业务代码处理
@Transactional public int insertUser(User user) { int i = userMapper.insertUser(user); if (i > 0) { System.out.println("success"); } int j = 10 / 0; return i; }
总结
以上所述是小编给大家介绍的SpringMVC+MyBatis 事务管理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍SpringMVC+MyBatis声明式事务管理,包括了SpringMVC+MyBatis声明式事务管理的使用技巧和注意事项,需要的朋友参考一下 采用的基本搭建环境:SpringMVC、MyBatis、MySQL、tomcat Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的
本文向大家介绍浅谈MyBatis 事务管理,包括了浅谈MyBatis 事务管理的使用技巧和注意事项,需要的朋友参考一下 1. 运行环境 Enviroment 当 MyBatis 与不同的应用结合时,需要不同的事务管理机制。与 Spring 结合时,由 Spring 来管理事务;单独使用时需要自行管理事务,在容器里运行时可能由容器进行管理。 MyBatis 用 Enviroment 来表示运行环境,
本文向大家介绍SpringMVC与Mybatis集合实现调用存储过程、事务控制实例,包括了SpringMVC与Mybatis集合实现调用存储过程、事务控制实例的使用技巧和注意事项,需要的朋友参考一下 在SSM框架中经常会用到调用数据库中的存储过程、以及事务控制,下面以保存某单据为例,介绍一下: 1、Oracle中存储过程代码如下(主要逻辑将单据编码自动加1,并将该单据编码返回): 2、Mybati
事务处理(transaction processing) 可以用来维护数据的完整性,保证SQL的操作要么完全执行,要么完全不执行,如果发生错误就进行撤销。 保证数据的完整性。 保证数据不受外影响。 事务处理的几道术语 事务(transaction) 一组SQL语句 退回(rollback)撤销执行SQL语句的过程 提交(commit) 将为执行的SQL语句写入数据库表 保留点(savepoint)
17. 事务管理
数据库的事务就是将任意多个SQL语句看作一个整体,只有这些SQL语句都成功执行,DBMS才会保存这些SQL语句对数据库的修改(事务提交)。否则,数据库将恢复到执行SQL语句之前的状态(事务回滚)。大多数DBMS都支持两种事务模式:隐式模式和显式模式。当执行每一条SQL语句时,无需进行事务提交,就可以直接将修改结果保存到数据库中。这叫做隐式事务模式。显式模式必须使用相应的语句或命令开起事务、提交事务