Использование транзакций в DAO - PullRequest
1 голос
/ 31 декабря 2011

Я использую Hibernate 3.6.9 с Atomikos и Spring 3.1.После прочтения Куда относится аннотация @Transactional? Я удалил аннотации @Transactional из всех DAO и оставил их только в Сервисе.После удаления этих аннотаций в любой операции dao db я получаю

org.hibernate.HibernateException: Unable to locate current JTA transaction

Моя конфигурация:

    <tx:annotation-driven transaction-manager="jtaTransactionManager" />


    <!-- Configure the Spring framework to use JTA transactions from Atomikos -->
    <bean id="jtaTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="atomikosTransactionManager" />
        <property name="userTransaction" ref="atomikosUserTransaction" />
    </bean>

    <!-- Construct Atomikos UserTransactionManager, needed to configure Spring -->
    <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
        init-method="init" destroy-method="close">

        <!-- when close is called, should we force transactions to terminate or 
            not? -->
        <property name="forceShutdown" value="false" />
    </bean>

    <!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
    <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">

        <property name="transactionTimeout" value="300" />
    </bean>

Свойства фабричной сессии:

                <prop key="hibernate.connection.isolation">3</prop>
                <prop key="hibernate.current_session_context_class">jta</prop>
                <prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory
                </prop>
                <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
                </prop>

Как мне управлять DAOтранзакции, и как я могу использовать DAO вне Сервиса?Это единственный способ решить эту проблему, чтобы запустить транзакции вручную (Transactional с распространением require_new) в любом слое, который использует daos?Однако при использовании Transactional с DAO я столкнулся с проблемами с отложенными исключениями инициализации (транзакция закрывается до уровня представления - пытается инициализировать поля сущности).

Edit:

Как мне следует управлять транзакциями, когдаКонтроллер Spring MVC может получить доступ непосредственно DAO?Должен ли контроллер быть транзакционным?

Моя проблема также появляется во время процесса входа в систему, потому что Spring Security использует dao (без @Transactional), поэтому ни один слой не запускает транзакцию?

Добавление @Transactional, например, к daos, используемымSpring security решает проблему -> когда есть @Transactional, все работает, но без этой аннотации использовать db невозможно.Но добавление @Transactional в некоторые DAO вызывает проблемы, потому что, когда Spring mvc хочет отобразить некоторые данные, появляется исключение отложенной инициализации, и тогда работает только ручной Hibernate.initialize в dao (потому что последний @Transactional закрывает транзакцию перед уровнем представления!).

Ответы [ 2 ]

1 голос
/ 31 декабря 2011

IMO, вы должны инициализировать те поля объектов в DAO, которые позже понадобятся на уровне представления.

Если нетерпеливая инициализация этих объектов кажется вам несколько «грязной», вы должны представить новые классы, специфичные для уровня представления (viewmodel), которые отображаются вашим уровнем обслуживания (у которого все еще есть открытая транзакция для чтения, еслинеобходимо).

Поскольку у меня нет Java-фона, я не знаю, нужен ли "весенней безопасности" доступ к базе данных.Если это произойдет, вы должны добавить эти транзакционные атрибуты и на соответствующий уровень обслуживания, как вы уже узнали.Тем не менее, я не думаю, что вы обязательно должны использовать транзакционные атрибуты вокруг методов DAO, что часто составляет один уровень.

0 голосов
/ 31 декабря 2011

Нет, ошибка говорит вам о настройке менеджера транзакций JTA:

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/transaction/jta/JtaTransactionManager.html

Выберите тот, который лучше всего подходит для вашей ситуации.

Этот вопрос форума Hibernate также может быть уместным:

https://forum.hibernate.org/viewtopic.php?p=2430788

Контроллеры должны не быть транзакционными. Вы получили их в нужном месте - они принадлежат службам.

OpenSessionInView может быть вашим решением:

http://springtips.blogspot.com/2007/07/open-session-in-view.html

Или не может быть:

Почему открытая сессия Hibernate считается плохой практикой?

...