我正在使用带有DAO模式的Hibernate和
Spring(* DAO.java类中的所有Hibernate依赖项).我有九个单元测试(JUnit),它们创建一些业务对象,保存它们,并对它们执行操作;对象是哈希(所以我一直在重用相同的对象).
我的JUnit设置方法调用我的DAO.deleteAllObjects()方法,该方法为我的业务对象表(只有一个)调用getSession().createSQLQuery(“DELETE FROM< tablename>”).executeUpdate().
我的一个单元测试(#8/9)冻结了.我认为这是一个数据库死锁,因为Hibernate日志文件最后显示我的删除语句.但是,调试显示它只是HibernateTemplate.save(someObject)冻结了. (Eclipse显示它在HibernateTemplate.save(Object)第694行冻结.)
另外值得注意的是,单独运行此测试(不在9个测试的套件中)不会导致任何问题.
我该如何排除故障并修复此问题?
另外,如果重要的话,我正在使用@Entity注释.
编辑:我删除了业务对象的重用(在每个方法中使用唯一对象) – 没有区别(仍然冻结).
编辑:这也开始流入其他测试(不能运行多个测试类而不会冻结某些东西)
编辑:将冻结测试分为两类.我现在要这样做,因为可耻的非干,因为它有两个或更多的测试类单元测试同一个业务对象类.
交易配置:
<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>
最佳答案 当冻结发生时,破坏应用程序,找到主线程并捕获堆栈跟踪.直到找到正在运行的数据库中阻塞的数据库查询.
你提到运行测试它自己的工作正常但运行完整套件会导致问题.如果是这种情况,那么我猜测其中一个先前的测试仍然打开了一个事务,并且在阻塞测试试图访问的某些行上有锁.
你的测试同时进行吗?如果是这样就停止这样做,因为它们可能互相干扰.
打开hibernate.show_sql选项,这样您就可以在控制台中看到生成的所有SQL.
在发生冻结时,您可以找出DB中锁定的行.例如在SQLServer中,您可以运行sp_lock来查看此信息,并运行sp_who以查看哪些SQL进程ID在另一个上阻塞.