如何在 MyBatis 中使用 Spring 设置事务隔离级别

How to set the Transaction isolationlevel using Spring with MyBatis

我喜欢自己设置 Isolationlevel,使用 Spring Framework 中的 transactionmanager 结合 myBatis。我尝试了很多教程,但没有任何效果。

我的应用程序构建为 MVC 模式,这意味着我有视图、模型、用于从 mybatis 进行依赖注入的接口和控制器 class。

我希望有人能给我建议我是mybatis的新手并且spring。整个应用程序 运行 非常好,但我喜欢接管对隔离级别的控制。

This is the spring-configuration.xml file
        <!--<mybatis-spring:scan base-package="de.hrw.model.**"/> -->
    <mybatis-spring:scan base-package="de.hrw.*" />
    <context:component-scan base-package="de.hrw.*" />



     <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/carrental">
        </property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="autoCommit" value="false"></property>
        <property name="registerMbeans" value="true"></property>
        <property name="transactionIsolation"
            value="TRANSACTION_SERIALIZABLE">
        </property> 
    </bean>


    <bean id="sqlSessionFactoryBean"
        class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property> 
        <property name="configLocation" value="classpath:mybatis-config.xml">
        </property>     
    </bean>

    <bean id="carController" class="de.hrw.controller.CarController">
        <property name="transactionManager" ref="transactionManager" /> 
    </bean>

    <bean id="carSearchView" class="de.hrw.view.CarSearchView">
    </bean>


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

    <tx:annotation-driven transaction-manager="transactionManager"/>

我正在使用 mybatis 的依赖注入从数据库中获取数据

接口示例 包裹 de.hrw.mgmtDAO;

进口java.util.List;

import de.hrw.model.CarModel;


public interface ICarMgmt {
    public CarModel selectCarById(final int carId);     
    public List<CarModel> selectAllCars(); 
}

这是主要的-class,我在其中包含一个视图(框架)

public class Carrental_main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

          ApplicationContext context = 
                  new ClassPathXmlApplicationContext("spring-config.xml");

          CarController carController = (CarController) context.getBean("carController");

          carController.openSearchView();
          carController.getCarSearchView().setVisible(true);
    }       

}

这是控制器。在这里我尝试将隔离级别设置为 SERIALIZABLE 但它始终设置为默认值 (-1)

@Transactional(propagation=Propagation.REQUIRES_NEW , isolation = Isolation.SERIALIZABLE)
public class CarController {
    @Autowired
    private ICarMgmt carMgmt;

private CarSearchView carSearchView;

private ApplicationContext applicationContext;
@Autowired
private PlatformTransactionManager transactionManager;

private TransactionStatus transactionStatus;

private TransactionDefinition defaultTransactionDefinition;

private DataSource dataSource;


public void openSearchView() {
    this.setApplicationContext();
    this.setDefaultTransactionDefinition();
    this.setTransactionStatus();

    this.carSearchView = (CarSearchView) applicationContext
            .getBean("carSearchView");


    try {

        List<CarModel> carList = carMgmt.selectAllCars();


        // this.carSearchView.setResultList(carList);
        this.carSearchView.setLabelList(carList);


        this.carSearchView.createTextFieldList();
        this.carSearchView.createLabelFieldList();


        transactionManager.commit(transactionStatus);

    } catch (DataAccessException e) {
        System.out.println("Error in creating record, rolling back");
        transactionManager.rollback(transactionStatus);
        throw e;
    }
}

 public void setDataSource(DataSource dataSource) {
          this.dataSource = dataSource;

       }

public void setDefaultTransactionDefinition() {
    this.defaultTransactionDefinition = new DefaultTransactionDefinition();
}

public void setApplicationContext() {
    applicationContext = new ClassPathXmlApplicationContext(
            "spring-config.xml");
}

public void setTransactionManager(
        PlatformTransactionManager transactionManager) {
    this.transactionManager = transactionManager;
}

public void setTransactionStatus() {
    this.transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);

}

你可以在mapper接口中应用如下所示的事务(虽然建议为class应用事务注释,但在mybatis中,接口中定义的事务将应用于代理class)

import java.util.List;
import de.hrw.model.CarModel;

@Transactional
public interface ICarMgmt {

    @Transactional(isolation = Isolation.SERIALIZABLE)
    public CarModel selectCarById(final int carId);

    public List<CarModel> selectAllCars(); 
}

我终于找到了解决办法。我将控制器中的 TransactionDefinition 对象更改为 DefaultTransactionDefinition 对象

private DefaultTransactionDefinition defaultTransactionDefinition;

以前是

private TransactionDefinition defaultTransactionDefinition;

但是TransactionDefinition没有提供任何设置方法。我想知道,因为在文档中我找到了设置隔离级别的方法,但这些方法只是由 DefaultTransactionDefinition 提供的。在我发现这个失败之后,我将以下内容添加到代码行中,它终于起作用了

defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
defaultTransactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_REPEATABLE_READ); 

感谢您的所有建议。如果有人知道 MyBatis + Spring 和事务管理器的非常好的教程,请 post a link :D