Использование @Transactional с JOOQ

Я пробую JOOQ, и первое, что я решил, это запустить транзакционный модульный тест, который автоматически откатится. Кажется, я не заставляю это работать, и я не уверен, куда идти отсюда. Логи показывают, что транзакция была запущена и откатилась. Но изменения по-прежнему фиксируются в базе данных.

Что я могу сделать, чтобы транзакции в Spring правильно работали с JOOQ?

2013-11-04 23:41:14,353 [main] DEBUG DataSourceTransactionManager: Creating new transaction with name [insertPersons]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2013-11-04 23:41:14,369 [main] DEBUG DataSourceTransactionManager: Acquired Connection [jdbc:mysql://localhost/jooq-learn, UserName=jooq@localhost, MySQL-AB JDBC Driver] for JDBC transaction
2013-11-04 23:41:14,376 [main] DEBUG DataSourceTransactionManager: Switching JDBC Connection [jdbc:mysql://localhost/jooq-learn, UserName=jooq@localhost, MySQL-AB JDBC Driver] to manual commit
2013-11-04 23:41:14,507 [main] DEBUG DataSourceTransactionManager: Initiating transaction rollback
2013-11-04 23:41:14,508 [main] DEBUG DataSourceTransactionManager: Rolling back JDBC transaction on Connection [jdbc:mysql://localhost/jooq-learn, UserName=jooq@localhost, MySQL-AB JDBC Driver]
2013-11-04 23:41:14,509 [main] DEBUG DataSourceTransactionManager: Releasing JDBC Connection [jdbc:mysql://localhost/jooq-learn, UserName=jooq@localhost, MySQL-AB JDBC Driver] after transaction
2013-11-04 23:41:14,509 [main] DEBUG DataSourceUtils: Returning JDBC Connection to DataSource

Мой тест выглядит так:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(TestConstants.contextConfigFile)
public class JooqTest {

    private static final Logger logger = LoggerFactory.getLogger(JooqTest.class);

    private PersonService personService;


    @Inject
    public void setPersonService(PersonService personService) {
        this.personService = personService;
    }


    @Test
    @Transactional
    public void insertPersons() {
        PersonRecord john = new PersonRecord();
        john.setName("John");
        john.setAge(45);
        personService.save(john);
    }
}

Я взял конфигурацию контекста Spring с веб-сайта JOOQ:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      init-method="createDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/jooq-learn"/>
    <property name="username" value="jooq"/>
    <property name="password" value="*****"/>
</bean>


<bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="dataSource"/>
</bean>


<bean id="transactionAwareDataSource"
      class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <constructor-arg ref="dataSource"/>
</bean>


<bean class="org.jooq.impl.DataSourceConnectionProvider" name="connectionProvider">
    <constructor-arg ref="transactionAwareDataSource"/>
</bean>


<bean id="dsl" class="org.jooq.impl.DefaultDSLContext">
    <constructor-arg ref="config"/>
</bean>


<bean class="org.jooq.impl.DefaultConfiguration" name="config">
    <constructor-arg index="0" ref="connectionProvider"/>
    <constructor-arg index="1">
        <null/>
    </constructor-arg>
    <constructor-arg index="2">
        <null/>
    </constructor-arg>
    <constructor-arg index="3">
        <null/>
    </constructor-arg>
    <constructor-arg index="4">
        <null/>
    </constructor-arg>
    <constructor-arg index="5">
        <value type="org.jooq.SQLDialect">MYSQL</value>
    </constructor-arg>
    <constructor-arg index="6">
        <null/>
    </constructor-arg>
    <constructor-arg index="7">
        <null/>
    </constructor-arg>
</bean>

person Bart    schedule 04.11.2013    source источник
comment
У вас правильно настроен MySQL с транзакционными таблицами? Если транзакции MyISAM не поддерживаются, для этого вам нужны таблицы типа InnoDB. Можете ли вы опубликовать свой полный тестовый пример, а не только метод.   -  person M. Deinum    schedule 05.11.2013
comment
Да, это действительно таблица MyISAM. Я воссоздам таблицу и посмотрю, что произойдет. Я также обновил тест, включив в него весь тестовый набор.   -  person Bart    schedule 05.11.2013
comment
Тест в порядке, никаких дальнейших проблем, просто измените тип таблицы.   -  person M. Deinum    schedule 05.11.2013
comment
@M.Deinum M.Deinum Я переключился на InnoDB, и теперь он работает, как и ожидалось. Вы спасли мой день :) Не могли бы вы написать ответ, чтобы я мог должным образом вознаградить вас?   -  person Bart    schedule 05.11.2013


Ответы (1)


MySQL (по крайней мере, более старые версии) по умолчанию использует MyISAM как тип таблицы, этот тип таблицы не поддерживает транзакции (см. таблицу 14.7 для вариантов поддержки). Вам нужно переключиться на таблицы InnoDB, которые поддерживают транзакции.

MyISAM Storagte Engine FeaturesИсточник: MySQL документация

Ссылки

person M. Deinum    schedule 05.11.2013