我有一个需求,需要在单个DAO类中使用两个不同的数据库。其中一个数据库是读写的,另一个是只读的。
我创建了2个数据源、2个会话工厂和2个事务管理器(读写数据库的事务管理器是平台事务管理器)。我在服务方法上使用@Transactional来配置Spring进行事务管理。
当我们在DAO类中调用sessionFactory.getCurrentSession()时,我们会遇到随机的“Session is closed!”异常(我不能总是复现它,有时正常工作,有时出错):
我没有使用全局事务(XA)的要求,我只想查询2个不同的数据库。
我已经阅读了这个帖子,它建议在DAO层注入两个单独的session工厂,就像我们现在所做的一样:Session factories to handle multiple DB connections 此外,根据这个答案,AbstractRoutingDataSource不能用于单个Dao类:https://dev59.com/EFvUa4cB1Zd3GeqPqin2#7379048 我的dao示例代码如下:
我也尝试过使用“doInHibernate”方法。但传递给它的会话也随机抛出“Session is closed!”异常:
我创建了2个数据源、2个会话工厂和2个事务管理器(读写数据库的事务管理器是平台事务管理器)。我在服务方法上使用@Transactional来配置Spring进行事务管理。
当我们在DAO类中调用sessionFactory.getCurrentSession()时,我们会遇到随机的“Session is closed!”异常(我不能总是复现它,有时正常工作,有时出错):
org.hibernate.SessionException: Session is closed!
at org.hibernate.internal.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:133)
at org.hibernate.internal.SessionImpl.setFlushMode(SessionImpl.java:1435)
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:99)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
我没有使用全局事务(XA)的要求,我只想查询2个不同的数据库。
我已经阅读了这个帖子,它建议在DAO层注入两个单独的session工厂,就像我们现在所做的一样:Session factories to handle multiple DB connections 此外,根据这个答案,AbstractRoutingDataSource不能用于单个Dao类:https://dev59.com/EFvUa4cB1Zd3GeqPqin2#7379048 我的dao示例代码如下:
Criteria criteria = sessionFactory1.getCurrentSession().createCriteria(MyClass.class);
criteria.add(Restrictions.eq("id", id));
criteria.list();
criteria = sessionFactory2.getCurrentSession().createCriteria(MyClass2.class); // generates random "Session is closed!" error.
criteria.add(Restrictions.eq("id", id));
criteria.list();
我也尝试过使用“doInHibernate”方法。但传递给它的会话也随机抛出“Session is closed!”异常:
@Autowired
protected HibernateTemplate hibernateTemplate;
@SuppressWarnings("unchecked")
protected List<Map<String, Object>> executeStaticQuery(final String sql) {
HibernateCallback<List<Map<String, Object>>> hibernateCallback = new HibernateCallback<List<Map<String, Object>>>() {
@Override
public List<Map<String, Object>> doInHibernate(Session session) throws HibernateException {
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
return query.list();
}
};
return hibernateTemplate.execute(hibernateCallback);
}