在我的应用程序中,hibernate事务由spring aop管理,并使用Teradata作为数据库。
这个问题特定于TERADATA,而且相同的代码在MYSQL中运行良好。
有一个服务类,即ServiceClass。
它有一个名为save
的方法,它将对象列表作为参数,并通过使用数据库中的数据进行检查来检查它是否被修改。
之后,它调用DAO类,该类将数据保存在数据库中。
ServiceClass方法的aop:
<tx:advice id="txAdviceForService"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save" isolation="READ_COMMITTED"/>
</tx:attributes>
</tx:advice>
服务类:
public void save(List<Test> testList) {
DAOClass daoClass;
boolean isUpdated = false ;
for (Test test : testList) {
Test testInDB = this.sessionFactory.getCurrentSession().get(
Test.class, test.getId());
if(! test.getName().equals(testIndDB)) {
isUpdated = true ;
break;
}
}
daoClass.save(testList);
if(isUpdated) {
// do some processing
}
}
DAOClass:
public void save(List<Test> testList) {
for (Test test : testList) {
try {
this.sessionFactory.getCurrentSession().saveOrUpda te(test);
session.flush();
} catch (HibernateException e) {
///
}
}
}
DAOClass method's aop:
<tx:advice id="txAdviceForDAO"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>
交易管理代码:
<aop:config>
<aop:advisor advice-ref="txAdviceForService"
pointcut="execution(* ServiceClass.*(..))" />
<aop:advisor advice-ref="txAdviceForDAO"
pointcut="execution(* DAOClass.*(..))" />
</aop:config>
这里,当服务类调用DAO类的save方法时,它会在AOP代码中如上所述在新事务中启动。
问题是服务类在一个事务中从数据库中读取对象,然后调用启动新事务以保存数据的方法。 当它调用session.flush时,表会被锁定,甚至无法从外部应用程序访问,并且应用程序被挂起。
如果我将从DAO保存数据的代码放到服务类中,那么它可以正常工作,因为它处于相同的事务中。
在使用Hibernate和Teradata(使用Spring托管事务)时,是否有人遇到类似的问题?