SpringMVC+MyBatis 事务管理(实例)

前言

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 事务管理,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Spring Boot多数据源及其事务管理配置方法

    准备工作 先给我们的项目添加Spring-JDBC依赖和需要访问数据库的驱动依赖. 配置文件 spring.datasource.prod.driverClassName=com.mysql.jdbc.Driver spring.datasource.prod.url=jdbc:mysql://127.0.0.1:3306/prod spring.datasource.prod.username=root spring.datasource.prod.password=123456 spring

  • SpringBoot JPA实现增删改查、分页、排序、事务操作等功能示例

    今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能. 下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and 关键字,比如 findByHeightAndSex(int height,char sex): public List<User> findByHeightAndSex(int height,char sex); // Or --- 等价于 SQL 中的 or 关键字,比如 findByHei

  • SpringMVC与Mybatis集合实现调用存储过程、事务控制实例

    在SSM框架中经常会用到调用数据库中的存储过程.以及事务控制,下面以保存某单据为例,介绍一下: 1.Oracle中存储过程代码如下(主要逻辑将单据编码自动加1,并将该单据编码返回): CREATE OR REPLACE PROCEDURE "UPDATE_DJBHZT" (p_GSID in varchar2, p_TBLNAME in varchar2, NewRecNo out Number) as begin update BHDJ set BHDJ02 = BHDJ02+1 w

  • springboot开启声明式事务的方法

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就默认开启.当然,如果你需要用其他的orm,比如beatlsql,就需要自己配置相关的事物管理器. 准备阶段 以上一篇文章的代码为例子,即springboot整合mybatis,上一篇文章是基于注解来实现mybatis的数据访问层,这篇文章基于xml的来实现,并开启声明式事务. 环境依赖 在pom文件

  • 详解SpringBoot的事务管理

    Springboot内部提供的事务管理器是根据autoconfigure来进行决定的. 比如当使用jpa的时候,也就是pom中加入了spring-boot-starter-data-jpa这个starter之后. Springboot会构造一个JpaTransactionManager这个事务管理器. 而当我们使用spring-boot-starter-jdbc的时候,构造的事务管理器则是DataSourceTransactionManager. 这2个事务管理器都实现了spring中提供的Pl

  • 详解基于spring多数据源动态调用及其事务处理

    需求: 有些时候,我们需要连接多个数据库,但是,在方法调用前并不知道到底是调用哪个.即同时保持多个数据库的连接,在方法中根据传入的参数来确定. 下图的单数据源的调用和多数据源动态调用的流程,可以看出在Dao层中需要有一个DataSource选择器,来确定到底是调用哪个数据源. 实现方式 对Dao层提供一个公共父类,保持有多个数据源的连接(本人是基于iBatis,即保持多个SQLSessionTemplate) /** * Created by hzlizhou on 2017/2/6. */ p

  • Spring 事务隔离与事务传播的详解与对比

    Spring 事务隔离与事务传播的详解与对比 Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置:编程式就是用注解的方式写到代码里. Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSource. Tr

  • 完美解决Spring声明式事务不回滚的问题

    疑问,确实像往常一样在service上添加了注解 @Transactional,为什么查询数据库时还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚.于是就对相关代码进行了一番测试,结果发现一下踩进了两个坑,确实是事务未回滚导致的数据不一致. 下面总结一下经验教训: Spring事务的管理操作方法 编程式的事务管理 实际应用中很少使用 通过使用TransactionTemplate 手动管理事务 声明式的事务管理 开发中推荐使用(代码侵入最少) Spring的声明式事

  • SpringMVC+MyBatis 事务管理(实例)

    前言 spring事务管理包含两种情况,编程式事务.声明式事务.而声明式事务又包括基于注解@Transactional和tx+aop的方式.那么本文先分析编程式注解事务和基于注解的声明式事务. 编程式事务管理使用TransactionTemplate或者PlatformTransactionManager.对于编程式事务spring推荐使用TransactionTemplate. 一.编程式事务 spring事务特性 spring中所有的事务策略类都继承自org.springframework.

  • Spring+SpringMVC配置事务管理无效原因及解决办法详解

    一般我们在Spring的配置文件application.xml中对Service层代码配置事务管理,可以对Service的方法进行AOP增强或事务处理如事务回滚,但是遇到一个问题,在Controller类中调用Service层方法,配置的事务管理会失效,查询相关资料发现原因.其实Spring和SpringMVC俩个容器为父子关系,Spring为父容器,而SpringMVC为子容器.也就是说application.xml中应该负责扫描除@Controller的注解如@Service,而Spring

  • 浅谈MyBatis 事务管理

    1. 运行环境 Enviroment 当 MyBatis 与不同的应用结合时,需要不同的事务管理机制.与 Spring 结合时,由 Spring 来管理事务:单独使用时需要自行管理事务,在容器里运行时可能由容器进行管理. MyBatis 用 Enviroment 来表示运行环境,其封装了三个属性: public class Configuration { // 一个 MyBatis 的配置只对应一个环境 protected Environment environment; // 其他属性 ...

  • Spring中的事务管理实例详解

    本文实例讲述了Spring中的事务管理.分享给大家供大家参考.具体分析如下: 事务简介: 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性 事务就是一系列的动作,它们被当作一个单独的工作单元.这些动作要么全部完成,要么全部不起作用 事务的四个关键属性(ACID) ① 原子性(atomicity):事务室一个原子操作,有一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用 ② 一致性(consistency):一旦所有事务动作完成,事务就被提交.数据和资源就

  • Mybatis源码解析之事务管理

    目录 Mybatis事务管理 和Spring整合后的事务管理 Mybatis事务管理 我们可以在mybatis-config.xml中配置事务管理器的实现 <transactionManager type="JDBC"/> 当值为JDBC时,事务管理实现类为JdbcTransaction,底层利用数据库的Connection来管理事务 当值为MANAGED时,事务管理实现类为ManagedTransactionFactory,但它对事务的管理是一个空实现,将事务管理交给外部

  • SpringMVC+MyBatis声明式事务管理

    采用的基本搭建环境:SpringMVC.MyBatis.MySQL.tomcat Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的环境从你的代码里面配置不同的事务管理策略,Spring提供两种事务管理策略:一种是声明式事务管理策略,另一种是编程式事务管理策略,这里主要介绍声明式事务管理策略 由于采用的是SpringMVC. MyBatis,故统一采用了标注来声明Service.Controller 由于

  • springmvc与mybatis集成配置实例详解

    简单之美,springmvc,mybatis就是一个很好的简单集成方案,能够满足一般的项目需求.闲暇时间把项目配置文件共享出来,供大家参看: 1.首先我们来看下依赖的pom: <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.ve

  • SpringMVC mybatis整合实例代码详解

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 一.逆向工程生成基础信息 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis G

  • MyBatis在Spring环境下的事务管理

    MyBatis的设计思想很简单,可以看做是对JDBC的一次封装,并提供强大的动态SQL映射功能.但是由于它本身也有一些缓存.事务管理等功能,所以实际使用中还是会碰到一些问题--另外,最近接触了JFinal,其思想和Hibernate类似,但要更简洁,和MyBatis的设计思想不同,但有一点相同:都是想通过简洁的设计最大限度地简化开发和提升性能--说到性能,前段时间碰到两个问题: 1.在一个上层方法(DAO方法的上层)内删除一条记录,然后再插入一条相同主键的记录时,会报主键冲突的错误. 2.某些项

  • Spring SpringMVC,Spring整合MyBatis 事务配置的详细流程

    整合思路 (1)SSM是什么? Spring,SpringMVC,Mybastis (2)思路 搭建整合的环境,初始化环境 搭建Spring环境,配置完成并测试 (service层) 再使用Spring整合MyBatis框架,并测试(Dao层) 最后使用Spring整合SpringMVC框架,并测试(web层) SSM搭建环境 (1)数据库创建ssm (2)创建maven工程 (3)git (创建.gitignore来过滤不用提交的文件) (4)依赖框架 (5)log4j.properties

随机推荐