Transactions

As you may have expected, MyBatis-CDI provides annotation based transaction support.

By default, each method call will use an isolated session but if you want to enclose many method calls in a transaction, annotate the method with @Transactional.

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

NOTE Batch statements are held in the transactional context so you must use the @Transactional attribute to use the batch executor.

To enable transactions you need to activate the local transaction interceptor in 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>

With this setting, MyBatis-CDI will start a transaction before entering the transactional method and will commit it if it ends with no exception or any exception that is not a RuntimeException or explicitly indicated in the annotation property rollbackFor and the annotation property rollbackOnly is false.

If a transactional method has calls to other nested transactional methods, inner method annotations will be ignored, transaction will begin before calling the outer method and will end after it ends.

NOTE The local transaction interceptor uses a best-effort strategy. In case there are more than one SqlSessionFactorys it will try to commit or roll them all back one by one. LocalTransactionInterceptor cannot guarantee data consistency in this scenario, and it is only recommended when you are using at least one no-XA datasource. Otherwise you should use the JtaTransactionInterceptor instead. See the following section for the details.

JTA Transactions

In case you are using more than one datasource you should use the JTA transaction interceptor by configuring the beans.xml file as follows:


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

And configure MyBatis to to use the MANAGED transaction manager in mybatis-config.xml file.

<transactionManager type="MANAGED" />

The @Transactional annotation

The @Transactional annotation supports the following parameters:

Property Default Description
executorType ExecutorType.SIMPLE The MyBatis executor type
isolation Isolation.DEFAULT The transaction isolation level. The default value will cause MyBatis to use the default isolation level from the data source.
force false Flag to indicate that MyBatis has to force the transaction commit()
rollbackOnly false If true, the transaction will never be committed, but rather the rollback will be forced. That configuration is useful for testing purposes.
rollbackFor not set Indicates which exception types must cause a transaction rollback. In addition to the indicated exceptions, any RuntimeException will also cause a rollback.