一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。而不是给 MyBatis 创建一个新的特定的事务管理器,MyBatis-Spring 利用了存在于 Spring 中的 DataSourceTransactionManager。

一旦 Spring 的 PlatformTransactionManager 配置好了,你可以在 Spring 中以你通常的做法来配置事务。@Transactional 注解和 AOP(Aspect-Oriented Program,面向切面编程,译者注)样式的配置都是支持的。在事务处理期间,一个单独的 SqlSession 对象将会被创建和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。

一旦事务创建之后,MyBatis-Spring 将会透明的管理事务。在你的 DAO 类中就不需要额外的代码了。

标准配置

要 开 启 Spring 的 事 务 处 理 , 在 Spring 的 XML 配 置 文 件 中 简 单 创 建 一 个 DataSourceTransactionManager 对象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

指定的 DataSource 一般可以是你使用 Spring 的任意 JDBC DataSource。这包含了连接池和通过 JNDI 查找获得的 DataSource。

要注意, 为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的是同一个数据源,否则事务管理器就无法工作了。

容器管理事务

如果你正使用一个 JEE 容器而且想让 Spring 参与到容器管理事务(Container managed transactions,CMT,译者注)中,那么 Spring 应该使用 JtaTransactionManager 或它的容器指定的子类来配置。做这件事情的最方便的方式是用 Spring 的事务命名空间:

<tx:jta-transaction-manager />

在这种配置中,MyBatis 将会和其它由 CMT 配置的 Spring 事务资源一样。Spring 会自动使用任意存在的容器事务,在上面附加一个 SqlSession。如果没有开始事务,或者需要基于事务配置,Spring 会开启一个新的容器管理事务。

注 意 , 如 果 你 想 使 用 CMT , 而 不 想 使 用 Spring 的 事 务 管 理 , 你 就 必 须 配 置 SqlSessionFactoryBean 来使用基本的 MyBatis 的 ManagedTransactionFactory 而不是其它任意的 Spring 事务管理器:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
</bean>

编程式事务管理

MyBatis 的 SqlSession 提供指定的方法来处理编程式的事务。但是当使用 MyBatis-Spring 时, bean 将会使用 Spring 管理的 SqlSession 或映射器来注入。那就是说 Spring 通常是处理事务的。

你 不 能 在 Spring 管 理 的 SqlSession 上 调 用 SqlSession.commit() , SqlSession.rollback() 或 SqlSession.close() 方 法 。 如 果 这 样 做 了 , 就 会 抛 出 UnsupportedOperationException 异常。注意在使用注入的映射器时不能访问那些方法。

无论 JDBC 连接是否设置为自动提交, SqlSession 数据方法的执行或在 Spring 事务之外任意调用映射器方法都将会自动被提交。

如果你想编程式地控制事务,请参考 Spring 手册的 10.6 节。这段代码展示了如何手动使用在 10.6.2 章节描述的 PlatformTransactionManager 来处理事务。

DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatus status = txManager.getTransaction(def);
try {
userMapper.insertUser(user);
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);

注意这段代码展示了一个映射器,但它也能和 SqlSession 一起使用。

第四章 事务(MYBatis)的更多相关文章

  1. MyBatis 3(中文版) 第四章 使用注解配置SQL映射器

    本章将涵盖以下话题: l 在映射器Mapper接口上使用注解 l 映射语句 @Insert,@Update,@Delete,@SeelctStatements l 结果映射 一对一映射 一对多映射 l ...

  2. Java Persistence with MyBatis 3(中文版) 第二章 引导MyBatis

    MyBatis最关键的组成部分是SqlSessionFactory,我们可以从中获取SqlSession,并执行映射的SQL语句.SqlSessionFactory对象可以通过基于XML的配置信息或者 ...

  3. MySQL InnoDB四个事务级别 与 脏读、不反复读、幻读

    MySQL InnoDB事务隔离级别脏读.可反复读.幻读 希望通过本文.能够加深读者对ySQL InnoDB的四个事务隔离级别.以及脏读.不反复读.幻读的理解. MySQL InnoDB事务的隔离级别 ...

  4. Python--Redis实战:第四章:数据安全与性能保障:第7节:非事务型流水线

    之前章节首次介绍multi和exec的时候讨论过它们的”事务“性质:被multi和exec包裹的命令在执行时不会被其他客户端打扰.而使用事务的其中一个好处就是底层的客户端会通过使用流水线来提高事务执行 ...

  5. Mysql 四种事务隔离介绍以及锁机制

    还有很多不太懂,这里收集几份大佬文章“飞机票”,待我整理好了,再好好写一篇文章吧. MySQL的四种事务隔离级别 https://www.cnblogs.com/huanongying/p/70215 ...

  6. (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合

    http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...

  7. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  8. 《Linux内核设计与实现》读书笔记 第四章 进程调度

    第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的 ...

  9. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

随机推荐

  1. DMA&PIO

    DMA&PIO   DMA的英文拼写是“Direct Memory Access”,汉语的意思就是直接内存访问,是一种不经过CPU而直接从内存存取数据的数据交换模式.在DMA模式下,CPU只须 ...

  2. X64 Deep Dive

    zhuan http://www.codemachine.com/article_x64deepdive.html X64 Deep Dive This tutorial discusses some ...

  3. 【Javascript】Javascript横向/纵向合并单元格TD

    > 需求是这样滴(>_<) 在报表系统中,涉及“HTML的TD单元格的合并”恐怕为数不少. 比如,从DB查得数据并经过后台的整理后,可能是这样的: Table1     JOB TO ...

  4. vue项目优化,加快服务器端渲染速度

    1. CSS在开发模式中用import,在打包后用CDN min.js中做如下操作 if (process.env.NODE_ENV == 'development') { require('../x ...

  5. LeetCode: Maximal Rectangle 解题报告

    Maximal RectangleGiven a 2D binary matrix filled with 0's and 1's, find the largest rectangle contai ...

  6. Django 用ModelForm批量保存form表单(非常实用的方法) mfor_verity项目

    1.先看一下 Model 非常多 from django.db import models from users.models import UserProfile # Create your mod ...

  7. SSH高级应用(端口转发)

    转发自:http://www.cnblogs.com/sting2me/p/5167730.html 基于SSH协议的端口转发 [前言] 最近一直在使用ssh协议的端口转发(隧道)功能,完成对内网空透 ...

  8. UML笔记1

    UML包括 事物 结构:类,接口等等 行为:交互,状态改变等 分组:包,子系统等 注释 关系 依赖,关联(聚合,组合),泛化,实现 图 用例图,交互图(顺序图,协作图),类图,活动图,状态图等 扩展机 ...

  9. C中fread()函数的返回值

    这个问题很容易搞错,并导致很多问题,需要强调的是fread函数返回的并不是字节数. realRead = fread(buf,item,count,fp)    (每次读item大小的数据块,分cou ...

  10. if的另一个实现思路

    在一些场景中需要根据根据一个传入的额值来做不同的处理,而且if有很多层,此时如果一直写if代码就会雍容.一种比较好的方法就是写一个map列出与if对应的情况,然后map的value就能放一些方法或者其 ...