2016-05-18 5 views
0

Я пытаюсь заставить Spring Transaction Management работать в моем новом приложении Spring Boot + MyBatis.Spring Transaction Management не работает с Spring Boot + MyBatis?

До сих пор мне удалось получить все, что работает с минимальными проблемами - это просто правильное функционирование аннотации @Transactional. В настоящее время все операторы фиксируются немедленно независимо от того, аннотирован или нет метод.

Spring Boot делает так много конфигурации шаблонов для вас, что трудно найти недостающее звено.

Мои build.gradle содержит следующие зависимости:

compile("org.springframework.boot:spring-boot-starter-amqp") 
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:1.0.0") 
compile("mysql:mysql-connector-java:5.1.38") 

Мои application.properties содержит следующую конфигурацию источника данных:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://localhost:3306/my_db 
spring.datasource.username=my_user 
spring.datasource.password=my_pass 

Простой пример метода в компоненте, который не действует, как ожидается, является таким, как следует:

@Transactional 
public void performTransactionTest() throws Exception { 

    Person person = new Person(); 
    person.setPersonId(123); 
    personMapper.insert(person); 

    throw new Exception("This should force a rollback!"); 

} 

Исключение получается, но запись уже вставлена.

В настоящее время не существует документации по конфигурации транзакций для Spring Boot AND MyBatis вместе, но, насколько я понимаю, она должна в основном подключаться, как это было бы сделано вручную в приложении Spring + MyBatis, и где оно не работает, t - мы можем настроить его дальше. С тем, что я попытался следующие конфигурации в моей applicationContext.xml не повезло:

<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" /> 

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

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 

Я могу подтвердить, что даже без какого-либо из указанных выше конфигураций DataSourceTransactionManager сконфигурирован с тем же DataSource, который использует SqlSession MyBatis Картостроители.

Любая помощь или идеи, которые могут подтолкнуть меня в правильном направлении, были бы весьма полезны. Если вам нужна дополнительная информация, я рад предоставить ее!

Заранее благодарен!

Xandel

+0

Аннотирование частных методов не приносит пользы. см. http://stackoverflow.com/q/7085271/217324 –

+0

Редактировать вопрос - я могу подтвердить, что проблема все еще существует с помощью общедоступного метода. – Xandel

+0

также проверенные исключения не вызывают откат по умолчанию. –

ответ

0

Так что я получил это работает на аннотирования определение класса с @Transactional вместо определения метода.

Я не уверен, что это обычная практика. В документации Spring Управление загрузкой транзакций не делает это как то here но весна образец Mybatis действительно делает это таким образом в их документации here ...

Если кто-нибудь имеет дополнительную информацию, которая может объяснить это я с удовольствием отметить, что ответ как правильный.

На данный момент, однако, проблема решена.

EDIT

Возвращаясь к этой проблеме месяц позже я, наконец, добрался до сути. Здесь было два основных вопроса.

  1. Как Казуки правильно сказано, что вам нужно явно объявить, что откаты должны произойти для проверяемых исключений с помощью @Transactional(rollbackFor = Exception.class) аннотацию.

  2. «Границы транзакций создаются только тогда, когда надлежащим образом аннотированные методы вызываются через прокси-сервер Spring. Это означает, что вам нужно вызывать ваш аннотированный метод непосредственно через @Autowired bean-компонент или транзакция никогда не запустится». (Ссылка на этот источник ниже)

В моем примере кода я звонил this.performTransactionTest() из того же класса. Таким образом, транзакция будет проигнорирована. Если я вместо этого назову его через проводную ссылку на мой класс, например myAutoWiredBean.performTransactionTest(), все будет работать так, как ожидалось. Это также объясняет, почему появилось только аннотирование уровня класса, но это потому, что любой вызванный метод ссылался бы на проводной компонент.

Здесь представлены две статьи, которые были MAIOR для меня в понимании более тонких деталей управления транзакциями Spring. Огромное спасибо авторам Нитину Прабху и Тиму Мэттисону.

https://dzone.com/articles/spring-transaction-management

http://blog.timmattison.com/archives/2012/04/19/tips-for-debugging-springs-transactional-annotation/

Я надеюсь, что это помогает кто-то!

0

Поведение Spring управления транзакциями по умолчанию является фиксацией при возникновении исключения проверки (исключение или подкласс). Если вы хотите отменить транзакцию, вы можете исключить исключение из исключения (RuntimeException или подкласс). Также @Transactional (rollbackFor = Exception.class) - тот же результат.

Пожалуйста, попробуйте это.

Для получения дополнительной информации см http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#transaction-declarative-rolling-back

Спасибо.

Смежные вопросы