事务

正如所料,MyBatis-CDI 提供了基于注解的事务支持。

默认情况下,每个方法调用都将使用一个孤立的 session,但如果你希望在事务中包含许多方法调用,请使用 @Transactional

@Transactional
public void doSomethingInATransaction() {
  ...
  mapper.insertMyBean(...);
  mapper.updateMyBean(...);
  ...
}

NOTE 批处理语句保存在事务环境中,因此必须使用 @Transactional 属性才能使用批处理执行器。

要启用事务,你需要在中激活本地事务拦截器 beans.xml:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
   <interceptors>
      <class>org.mybatis.cdi.LocalTransactionInterceptor</class>
   </interceptors>
</beans>

在这种设置下,MyBatis-CDI 将在进入事务方法之前启动事务,如果事务结束时没有异常,或任何非 RuntimeException 的异常,或注解属性 rollbackFor 中明确指示的异常,则将提交该事务, 且属性 rollbackOnly 为 false。

如果一个事务方法有对其他嵌套事务方法的调用,则内部方法注解将被忽略,事务将在调用外部方法之前开始,事务将在它结束后结束。

NOTE 本地事务拦截器使用“尽力而为”的策略。如果有多个 SqlSessionFactory,它将尝试逐个提交或回滚它们。LocalTransactionInterceptor 无法保证此场景下的数据一致性,仅建议在有 no-XA 数据源时使用。否则,你应该改用JtaTransactionInterceptor。有关详细信息,请参阅以下部分。

JTA 事务

如果你使用多个数据源,则应通过如下配置 bean.xml 文件来使用 JTA 事务拦截器:

<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
   <interceptors>
      <class>org.mybatis.cdi.JtaTransactionInterceptor</class>
   </interceptors>
</beans>

并将 MyBatis-config.xml 文件中的事务管理器设置为 MANAGED。

<transactionManager type="MANAGED" />

@Transactional 注解

@Transactional 注解支持以下参数:

属性 默认值 描述
executorType ExecutorType.SIMPLE The MyBatis 执行器类型
isolation Isolation.DEFAULT 事务隔离级别。默认值将使 MyBatis 使用与数据源的默认隔离级别。
force false 表示 MyBatis 强制使用 commit() 提交事务。
rollbackOnly false 如果为 true,则永远不会提交事务,而是强制回滚。该配置对于测试目的很有用。
rollbackFor 未配置 指示哪些异常类型必须导致事务回滚。除了指示的异常之外,任何 RuntimeException 也将导致回滚。