DAO的交易用法

时间:2011-12-31 13:00:09

标签: hibernate spring transactions jta atomikos

我正在使用Hibernate 3.6.9与Atomikos和Spring 3.1。在阅读Where does the @Transactional annotation belong?之后,我已经从所有DAO中删除了@Transactional注释,并且我只将它们留在了服务上。在我收到的任何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?解决此问题的唯一方法是在任何使用daos的层中手动启动事务(Transactional with propagation requires_new)?但是当使用Transactional与DAO时,我遇到了延迟初始化异常的问题(事务在表示层之前关闭 - 尝试初始化实体字段)。

编辑:

当spring mvc的控制器可以直接访问DAO时,我应该如何管理事务?控制器应该是交易性的吗?

我的问题也出现在登录过程中,因为Spring安全性使用dao(没有@Transactional)所以没有层启动事务?

将@Transactional添加到例如spring security使用的daos解决了这个问题 - &gt;当有@Transactional时一切正常,但没有这个注释就无法使用db。但是将@Transactional添加到某些DAO会带来问题,因为当spring mvc想要显示某些数据时,会出现延迟初始化异常,然后只能在dao中手动Hibernate.initialize(因为最后@Transactional在表示层之前关闭了事务!)。

2 个答案:

答案 0 :(得分:1)

IMO,您应该初始化DAO中对象的那些字段,这些字段稍后在表示层中需要。

如果急切地初始化这些对象对你来说有些“脏”,你应该引入新的表示层特定类(视图模型),这些类由服务层映射到(如果需要,它仍然有一个打开的事务来读取)。

由于我没有Java背景,我不知道“spring security”是否需要访问数据库。如果是这样,您必须在相应的服务层上添加这些事务属性,如您已经发现的那样。但是,我认为你不一定要在DAO方法中放置事务属性,这通常是一个层次到深层次。

答案 1 :(得分:0)

不,错误告诉您配置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

或者它可能不会:

Why is Hibernate Open Session in View considered a bad practice?