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



我喜欢自己设置隔离级别,使用Spring框架中的事务管理器与myBatis结合使用。我试了很多教程,但都不起作用。

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

我希望有人能给我一些建议,我是一个初来乍到的人。整个应用程序运行得很好,但我想接管隔离级别的控制。
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;

进口并不知道;

import de.hrw.model.CarModel;

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

这是我包含view (frame)的主类

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,但它总是设置为default (-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);
}

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

private DefaultTransactionDefinition defaultTransactionDefinition;

former it was

private TransactionDefinition defaultTransactionDefinition;

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

defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
defaultTransactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_REPEATABLE_READ); 
谢谢你的建议。如果有人知道MyBatis + Spring和事务管理器的真正好的教程,请发布链接:D

您可以在mapper接口中应用如下所示的事务(尽管建议为类应用事务注释,但是在mybatis中,接口中定义的事务将应用于代理类)

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(); 
}

最新更新