首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Hibernate/Spring: getHibernateTemplate().save(…)冻结/悬挂

Hibernate/Spring: getHibernateTemplate().save(…)冻结/悬挂
EN

Stack Overflow用户
提问于 2011-01-08 17:48:30
回答 2查看 5.8K关注 0票数 5

我在DAO模式中使用Hibernate和Spring ( *DAO.java类中的所有Hibernate依赖项)。我有九个单元测试(JUnit),它们创建一些业务对象,保存它们,并对它们执行操作;对象在散列中(所以我一直在重用相同的对象)。

我的JUnit安装方法调用我的DAO.deleteAllObjects()方法,该方法为我的业务对象表调用getSession().createSQLQuery("DELETE FROM <tablename>").executeUpdate() (只有一个)。

我的一个单元测试(#8/9)被冻结了。我假定是数据库死锁,因为Hibernate日志文件最后显示了我的delete语句。但是,调试表明,冻结的仅仅是HibernateTemplate.save(someObject)。(Eclipse显示,在HibernateTemplate.save(Object)**,第694*行上发生了冰冻。)

同样有趣的是,单独运行这个测试(不是在9个测试的套件中)不会造成任何问题。

我到底该如何解决和解决这个问题呢?

此外,如果这很重要,我将使用@Entity注释。

编辑: --我删除了业务对象的重用(在每种方法中使用唯一的对象)--没有起到作用(仍然冻结)。

编辑:这个程序也开始渗透到其他测试中(不能运行一个以上的测试类而不需要冻结)

编辑:将冻结测试分解为两个类。我现在要这样做,就像有两个或多个测试类单元测试同一个业务对象类一样,这是可耻的。

事务配置:

代码语言:javascript
运行
复制
    <bean id="txManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
        <tx:attributes>
            <!-- all methods starting with 'get' are read-only -->
            <tx:method name="get*" read-only="true" />
            <tx:method name="find*" read-only="true" />
            <!-- other methods use the default transaction settings (see below) -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- my bean which is exhibiting the hanging behavior -->
    <aop:config>
    <aop:pointcut id="beanNameHere"
        expression="execution(* com.blah.blah.IMyDAO.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="beanNameHere" />
</aop:config>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-08 19:14:53

当冻结发生时,中断应用程序,找到主线程并捕获堆栈跟踪。深入了解,直到您准确地找到在DB中阻塞的DB查询。

您提到在它自己的工作上运行测试还行,但是运行完整的套件会导致问题。如果是这样的话,那么我猜前面的一个测试仍然打开了一个事务,并在阻塞测试试图访问的某些行上设置了锁。

您的测试是否同时运行?如果是这样的话,那就别再这样做了,因为他们可能会互相干扰。

打开hibernate.show_sql选项,以便在控制台中看到生成的所有SQL。

在发生冻结时,您可以找出哪些行被锁定在DB中。例如,在SQLServer中,您可以运行sp_lock来查看这一点,运行sp_who来查看在另一个进程上阻塞了哪些SQLServer。

票数 1
EN

Stack Overflow用户

发布于 2011-01-08 22:47:41

有几件事要检查:

  • 正确的事务管理--在您的配置中,您的DAO上有事务。通常,在服务层(而不是DAO )周围设置事务是可取的。但是无论如何--确保测试中围绕着dao使用了一个事务。或者让测试@Transactional (如果使用spring的junit运行程序)
  • 将数据源的日志记录更改为info (可能吗?)。它报告deadlocks.
  • watch数据库日志的死锁(如果有这样的选项)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4635252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档