【发布时间】:2016-11-24 18:15:25
【问题描述】:
我有一个 MQ 侦听器,它侦听消息并将状态更新到 DB。我有一个设置,其中 Hibernate 会话由 Spring 管理。
下面是MQ监听配置。
<bean id="queue" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="queuename" />
</bean>
<bean id="listenerBean" class="com.mypackage.Listener">
<property name="service" ref="myService" />
</bean>
<bean id="listener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg><ref bean="listenerBean"/></constructor-arg>
</bean>
<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queue" />
<property name="messageListener" ref="listener" />
<property name="exceptionListener" ref="exceptionListener" />
<property name="sessionTransacted" value="true" />
<property name="autoStartup" value="true" />
</bean>
在Java端处理MQ消息,
public class Listener implements MessageDelegate{
public MyService service;
@Override
public void handleMessage(Serializable message) {
service.process(message);
}
}
服务类中的 process 方法调用 DAO 方法来更新 DB。
以下是用于 Spring sessionFactory bean org.springframework.orm.hibernate3.LocalSessionFactoryBean 的休眠属性。
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache_db_custom.xml</prop>
</props>
</property>
这个 sessionFactory 被注入到我的 DAO bean 中,我使用 sessionFactory.getCurrentSession() 获取我的会话
使用这个session,我正在使用Criteria API 根据我从MQ 消息中获得的唯一值获取bean,对于我获得的唯一结果,我将状态更改为成功并再次调用sessionFactory.getCurrentSession() 到获取session 并调用session.update() 来更新数据库。
bean 上没有注释,因为我使用的是 hbm 文件。它是一个简单的 bean,没有一对多或多对一的映射。没有@Transactional 注释。
下面是更新sn-p。我相信 Spring 会处理事务。
Session session = sessionFactory.getCurrentSession();
if(session != null && bean != null) {
session.update(bean);
}
我有一个记录器(由我添加,log4j),用于在数据库更新失败时成功更新数据库并处理异常。
奇怪的部分来了。
我在多线程环境中遇到过一个场景,其中日志不显示休眠引发的任何异常,并且日志显示数据库已成功更新,但是状态未更新。这只发生在某些记录上,而不是全部。有成功更新的记录。我找不到任何特定于数据的问题。
当我执行使用 JUnit 更新失败的记录之一时,它更新成功。
如果我在配置结束时遗漏了什么,有人可以告诉我吗?
【问题讨论】:
-
您能添加您的 MQ 侦听器代码并告诉我们配置了多少侦听器吗?
-
@javaguy 更新了问题中的 MQ 侦听器代码。分布在 2 个服务器上的 8 个 JVM 上有 8 个监听器。
标签: java spring hibernate session