Как установить уровень изоляции транзакции с помощью Spring с MyBatis

Мне нравится устанавливать уровень изоляции самостоятельно, используя менеджер транзакций из Spring Framework в сочетании с myBatis. Я пробовал много учебников, но ничего не получалось.

Мое приложение построено как шаблон MVC, что означает, что у меня есть представления, модели, интерфейсы, используемые для внедрения зависимостей из mybatis и класса контроллера.

Я надеюсь, что кто-то может дать мне совет, я новичок в 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 для получения данных из базы данных и в нее.

пример пакета iterface de.hrw.mgmtDAO;

импортировать java.util.List;

import de.hrw.model.CarModel;


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

это основной класс, в который я включаю вид (кадр)

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

}

person Sigurius    schedule 30.05.2015    source источник
comment
Это выглядит правильно. Но вы уверены, что вам нужен SERIALIZABLE? Похоже, вам нужно как минимум InnoDB 5.5, чтобы получить поддержку для этого - mysql innodb реализует настоящую сериализуемую изоляцию"> stackoverflow.com/questions/6269471/   -  person AngerClown    schedule 31.05.2015
comment
Serializable предназначен только для тестирования. Я хочу получить ужас, если я вставлю один и тот же объект несколько раз подряд. Но это не работает. В beangraph я видел, что SessionBeanFactory и txManager не связаны. Макс быть есть Проблема. Но я понятия не имею, как их подключить.   -  person Sigurius    schedule 31.05.2015
comment
Какую весеннюю версию вы используете? А также версию mybatis?   -  person Ian Lim    schedule 01.06.2015
comment
MyBatis Версия 3.3.0 | MyBatis-Весна 1.2.2 | весна-Контекст 4.1.6 | ИнноДБ 5.6   -  person Sigurius    schedule 01.06.2015


Ответы (2)


Я наконец нашел решение. Я изменил объект TransactionDefinition в контроллере на объект DefaultTransactionDefinition.

private DefaultTransactionDefinition defaultTransactionDefinition;

раньше это было

private TransactionDefinition defaultTransactionDefinition;

но TransactionDefinition не предоставляет никаких методов настройки. Мне было интересно, потому что в документации я нашел такие методы для установки уровня изоляции, но эти методы просто предоставлены DefaultTransactionDefinition. После того, как я обнаружил этот сбой, я добавил следующие строки кода, и он, наконец, работает

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

Спасибо за все ваши советы. Если кто-то знает действительно хороший учебник по MyBatis + Spring и менеджеру транзакций, пожалуйста, опубликуйте ссылку: D

person Sigurius    schedule 01.06.2015

Вы можете применить транзакцию, как показано ниже, в интерфейсе картографа (хотя рекомендуется применять аннотацию транзакции для класса, однако в 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(); 
}
person Karthik Prasad    schedule 01.06.2015