我在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注释。
编辑: --我删除了业务对象的重用(在每种方法中使用唯一的对象)--没有起到作用(仍然冻结)。
编辑:这个程序也开始渗透到其他测试中(不能运行一个以上的测试类而不需要冻结)
编辑:将冻结测试分解为两个类。我现在要这样做,就像有两个或多个测试类单元测试同一个业务对象类一样,这是可耻的。
事务配置:
<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>发布于 2011-01-08 19:14:53
当冻结发生时,中断应用程序,找到主线程并捕获堆栈跟踪。深入了解,直到您准确地找到在DB中阻塞的DB查询。
您提到在它自己的工作上运行测试还行,但是运行完整的套件会导致问题。如果是这样的话,那么我猜前面的一个测试仍然打开了一个事务,并在阻塞测试试图访问的某些行上设置了锁。
您的测试是否同时运行?如果是这样的话,那就别再这样做了,因为他们可能会互相干扰。
打开hibernate.show_sql选项,以便在控制台中看到生成的所有SQL。
在发生冻结时,您可以找出哪些行被锁定在DB中。例如,在SQLServer中,您可以运行sp_lock来查看这一点,运行sp_who来查看在另一个进程上阻塞了哪些SQLServer。
发布于 2011-01-08 22:47:41
有几件事要检查:
@Transactional (如果使用spring的junit运行程序)info (可能吗?)。它报告deadlocks.https://stackoverflow.com/questions/4635252
复制相似问题