Spring @transactional ведет себя странно с mode = aspectj - PullRequest
3 голосов
/ 16 октября 2011

Я пытался заставить Spring-транзакции нормально работать в моем приложении в течение нескольких дней, и теперь мне некуда обратиться, кроме сообщества.Заранее благодарю за помощь.

У моего приложения есть особые требования, в которых мне нужно аннотировать защищенный переопределенный метод с помощью @Transactional и вызывать этот метод из абстрактного родительского класса.Из того, что я прочитал, я не могу использовать прокси и должен использовать mode = aspectj.

Во-первых, некоторая конфигурация:

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

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

<context:load-time-weaver />

<bean name="ID_DataAccessor" class="dal.DataAccessor">
    <constructor-arg ref="dataSource" />
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost" />
           .....
    <property name="defaultAutoCommit" value="true" />
</bean>

Если я использую аннотацию @Transactional для методав ID_DataAccessor соединение является транзакционным (DataSourceUtils.isConnectionTransactional(c, dataSource) == true).Это бесполезно для меня, потому что транзакция фиксируется, как только метод завершен.Когда я использую @Trasnactional для метода, который вызывает метод в DataAccessor, соединение, полученное в DataAccessor (из DataSourceUtils.getConnection(dataSource)), НЕ является транзакционным.Кроме того, я помещаю точку останова в DataSourceTransactionManager.doGetTransaction (), и она вызывается только в том случае, если аннотация @Transactional находится непосредственно в методе, получающем соединение.Простите за перегрузку терминологии, но похоже, что аннотация @Transactional не распространяется по стеку.

Я совершенно сбит с толку.Пожалуйста помоги!:)

1 Ответ

3 голосов
/ 17 октября 2011

Я почти отказался от этого.Это было совершенно не очевидно.Ваша проблема вызвана использованием EndOfDayProcess класса в вашей точке входа .Это проблема, потому что это вызывает загрузку класса, и, в более общем смысле, он распространяется на любой из ваших классов * Process и * EntryPoint.На тот момент в вашем коде Spring еще не был запущен, поэтому ткач времени его загрузки не активен, и класс загружается нормально, без впутывания в него кода транзакции.Конечно, классы загружаются только один раз, поэтому они остаются, и когда вы создаете бин в Spring, это бин, чей тип не имеет никакого отношения к транзакциям, за исключением того, что на нем есть аннотации @Transactional.К тому времени уже никого не было, чтобы увидеть их.Я вижу два возможных (хороших) решения:

  1. Переключение на ткачество во время сборки.Тогда невозможно загрузить класс до того, как он соткан.
  2. Измените способ, которым вы определяете, какой * боб процесса использовать на основе точки входа.Используйте все, что вам нравится, за исключением того, что вызывает загрузку класса * Process.
...