前言

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;
}

参考资料

http://www.cnblogs.com/wyisprogramming/p/6944878.html

http://www.cnblogs.com/xusir/p/3650522.html

SpringMVC+MyBatis 事务管理一的更多相关文章

  1. springMVC+mybatis事务管理总结

    1.spring,mybatis事务管理配置与@Transactional注解使用: 概述事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性.Spring Framewo ...

  2. spring + springmvc+ mybatis 事务管理及控制

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  3. SpringMVC+MyBatis 事务管理二

    前言 上篇主要从编程式事务和声明式事务注解的形式来了解了事务,而这篇我们针对AOP的方式来实现事务.先回顾下事务的基础知识事务的隔离级别和事务的传播行为.使用aop 配置事务时注意引用aspectjw ...

  4. spring+mybatis事务管理

    spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...

  5. spring,mybatis事务管理配置与@Transactional注解使用[转]

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...

  6. 《深入理解mybatis原理》 MyBatis事务管理机制

    MyBatis作为Java语言的数据库框架,对数据库的事务管理是其很重要的一个方面.本文将讲述MyBatis的事务管理的实现机制. 首先介绍MyBatis的事务Transaction的接口设计以及其不 ...

  7. spring,mybatis事务管理配置与@Transactional注解使用

    spring,mybatis事务管理配置与@Transactional注解使用[转]   spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是 ...

  8. springboot mybatis 事务管理

    本文主要讲述springboot提供的声明式的事务管理机制. 一.一些概念 声明式的事务管理是基于AOP的,在springboot中可以通过@Transactional注解的方式获得支持,这种方式的优 ...

  9. Mybatis 事务管理

    mybatis的事务和数据源有着非常密切的联系.上文讲述了mybatis的数据源,本文要讲述的便是mybatis的事物 1.事务的分类 我们还是已一段xml配置文件为例 <environment ...

随机推荐

  1. PHP设计模式:抽象工厂

    示例代码详见https://github.com/52fhy/design_patterns 抽象工厂 抽象工厂(Abstract Factory)是应对产品族概念的.比如说,每个汽车公司可能要同时生 ...

  2. 使用linux sort给一个文件里的内容按规则排序

    任务:report.txt文件里有以下内容:记录了一些方法的执行时间,要求按执行时间降序排列. void com.dustpan.zeus.core.service.MergeService.star ...

  3. 16.如何做到webpack打包vue项目后,可以修改配置文件

    问题描述: 前端需要修改restful API的url,但是打包之后,配置文件找不到了,如果在npm run build 生成dist后,这个配置也被写死了,传到运行的前端服务器上后,假设某次,api ...

  4. pdf文件之itextpdf插入html内容以及中文解决方案

    简述 目前网上已经有很多种html文件直接转pdf的技术帖子,但是很少有直接将部分html作为段落插入到pdf中,而且也没有一个可以很好的解决中文显示的问题. 因此今天上午围绕这个问题进行了研究,把解 ...

  5. Eclipse 快捷键和模板设置

    快捷键设置 菜单  Window --> Preferences---General---Keys Content Assist:  代码提示快捷键 模板设置 新建一个模板 在Insert Va ...

  6. Unreal Engine 4 Radiant UI 入门教程(零)在场景中摆放网页

    相关的学习资源: https://forums.unrealengine.com/showthread.php?12097-PLUGIN-RadiantUI-SDK-UIs-HUDs-Interact ...

  7. .NET C#到Java没那么难,DB篇

    前言 .NET C#到Java没那么难,都是面向对象的语言,而且语法还是相似的,先对比一下开发环境,再到Servlet,再到MVC,都是一样一样的,只是JAVA的配制项比较多而已,只要配好一个,后面都 ...

  8. 包装类、数组、string类浅析及练习

    String s1 = "abc"; String s2 = "abc"; System.out.println(s1==s2); //返回true Strin ...

  9. Luogu 1090 合并果子(贪心,优先队列,STL运用)

    Luogu 1090 合并果子(贪心,优先队列,STL运用) Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每 ...

  10. 软件安装(JDK+MySQL+TOMCAT)

    一,JDK安装 1,查看当前Linux系统是否已经安装了JDK 输入 rpm -qa | grep java 如果有: 卸载两个openJDK,输入rpm -e --nodeps 要卸载的软件 2,上 ...