【问题标题】:Transactions usage in DAO'sDAO 中的交易使用情况
【发布时间】:2011-12-31 13:00:08
【问题描述】:

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

编辑:

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

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

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

【问题讨论】:

  • 我猜问题是您的服务上的@Transaction 注解没有被考虑在内。 -- 请发布带有事务注释的服务方法之一,以及带有调用该方法的语句的方法和启用事务注释支持的配置部分。
  • @Ralph 我已经扩展了我的问题。

标签: hibernate spring transactions jta atomikos


【解决方案1】:

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

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

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

【讨论】:

  • 通过在 dao 中初始化此字段来解决 lazili 初始化异常还有另一个缺点 - 我们仍在处理分离的对象。我正在考虑使用 OpenSessionInViewFilter 将会话范围扩展到表示层。
  • 您不应该尝试捕获异常,而是确保从您的服务层传递回表示层的对象包含所有需要的 - 因此已初始化 - 值。
【解决方案2】:

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

【讨论】:

  • 我已经按照 atomikos 文档中的描述配置了 JTA 事务管理器。
  • 类签名是否符合 Spring 的 JTA?如果没有,它将如何使用?抱歉,我对 Atomikos 不熟悉。查看 Hibernate 论坛问题。它谈到了会话问题。
猜你喜欢
  • 2018-06-18
  • 2019-10-11
  • 2018-12-20
  • 2021-05-30
  • 1970-01-01
  • 2023-03-13
  • 2012-06-28
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多