开源项目

知识点

相关文章

更多

最近更新

更多

MyBatis-Spring 事务管理DataSourceTransactionManager

2019-05-06 23:29|来源: 网路

一个使用 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 一起使用。

相关问答

更多
  • 我是用的spring集成的 1可以用aop,切面控制事务 2可以用注解控制事务(申明式事务) 3编程式事务 jdbc.xml java代码: 申明式事务,关键字@Transactional @Transactional public int Save1(String name, String hometown) { Person person = new Person(); person.setName(name); person.setHometown(hometown); int i = personD ...
  • 所以尽管 MyBatis3 提供了对 Spring 的整合,但是 org.springframework.jdbc.datasource.DataSourceTransactionManager 这个事务管理 器还是不支持
  • 首先要明确 既然用了ssh框架 事务是由spring管理,而不是手动开启关闭。所以你要注意的不是怎么开,怎么关 而是得知道 什么时候开 什么时候关 expression=" execution(* com.haier..service..impl.*ServiceImpl.*(..))"> 这里的配置文件 自动的对service层的方法进行了管理事务 而配置文件里的下面这个代码中的 REQUIRED属性对一个session里有2个以上事务时候,统一采用第一个事务 再有一般dao层采用currentSessi ...
  • 事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。 这样可以防止出现脏数据,防止数据库数据出现问题。 开发中为了避免这种情况一般都会进行事务管理。 在JDBC中是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。 Hibernate中是通过Transaction进行事务 ...
  • 有难同当,有福同享! 有一条不执行就都不执行,都可以执行的话就执行 晕,数据库执行操作的时候不得commit一下才会成功嘛,事务就是吧commit放到两条执行语句下面了,如果都成功了,执行commit,有一条出错,就抛异常,可以写成个代码样式: try{ sql1; sql2; commit; }catch(Exception e){ }
  • spring 3 的文档说 的 rollback-for 和 no-rollback-for 属性都没有默认值,那没有添加 rollback-for 的异常列表的话,那你知道当异常出现时 Spring 是回滚了事务还是提交了事务啊? 我没有实际使用过 Spring 的事务管理,不过从我在 EJB 2.0 声明式的事务的使用过程看,声明式的事务定义了在碰到哪些异常时应该自动回滚事务,哪些异常直接提交了,像 EJB 2.0 是说凡是系统异常(包括RuntimeException 及其 ...
  • 程序的一个执行单元,举个例子 银行转账,A转给B 100元 1、A的卡中扣掉100元 2、B的卡中增加100元 转账完成,这2个步骤就是一个事务。特点就是1和2必须保证同时成功,或同时失败。
  • 事务在实际开发中会有遇到,但个人觉得其实许多场景下完全可以不需要事务的;另外,尤其在面试的时候,会经常问你事务的问题。 Spring 的事务你需要了解: 1. 声明式事务(也就是需要在配置文件中配置,或者注解) 2. 编程式事务 (需要你在代码中控制事务的开始、提交、回滚) 大概了解一下,其实不难。
  • 给定的sqlSessionFactory只能关联一个数据源。 但这不是主要问题。 主要问题是本地缓存与mybatis会话相关联 。 因此,当您使用两个不同的会话时,您将拥有两个不同的本地缓存 - 每个会话一个,并且有一个sqlSessionFactory将无济于事。 您应该考虑的选项是为只读会话设置localCacheScope = STATEMENT。 在这种情况下,它不会在执行查询后缓存结果。 为了能够仍然使用缓存,可以使用自定义适配器为某些全局配置的缓存或使用全局缓存(例如ehcache)的现有缓存适 ...
  • 我在 @RisingDragon找到了解决方案: “如果你从另一个本地方法调用它,那么它将无法工作,因为spring无法知道它被调用并启动事务。 如果你是通过使用包含insertNotes()方法的类的自动对象从另一个类的方法调用它,那么它应该工作。“ 在我的例子中,我创建了第二个类 (例如RisingDragom的NoteClass)和一些@Transactional方法(例如我的代码中的insertUser)然后,回滚工作了!! 第二类出现在调试器中,尾部为“$$ EnhancedByCGLib” 。 ...