xiaoer 2009-07-15 05:32
浏览 334
已采纳

hibernate对多数据源的支持

hibernate最新版本(3.3)是否支持如下需求:

后台有多个物理数据库, master database 和 slave database1, slave database2, .....

数据库服务器自身负责完成master database和slave databases的数据同步。

我的问题是, 能否定义多个数据源, 通过配置或简单编码hibernate实现将所有的insert, update, delete等改变数据的操作都在master database中完成, 所有select操作分配在slave databases中完成。
[b]问题补充:[/b]
我想将单数据库系统升级为Master-Slave模式(Master写,Slave读)。

原系统简介:使用Struts+Hibernate架构;数据库连接池。

计划使用ReplicationDriver,考虑了一下。大致需要做以下三处改动。
1 用新的驱动程序替换旧驱动程序

2 修改连接池配置文件如下

3 修改DAO, 增加如下代码
session.connection().setReadOnly(true/false);

不知是否考虑完全,有哪些更好的建议?
[b]问题补充:[/b]
补充问题:

  1. ReplicationDriver对MySQL数据库的版本有要求吗? 我理解应该是没有要求。

  2. ReplicationDriver定义Master-Slave服务器就是通过排列顺序是吗? 排在第一的是Master,从第二个开始是Slave?

[b]问题补充:[/b]
做了简单测试,数据写入Master没有问题, 但读出数据为什么是从Master,而不是Slave。

连接池配置文件见第一次问题补充

CustomerDAO 测试代码如下:
[code="java"]
public class CustomerDAO {

private String DTO_NAME = "CustomerDTO";

public List find() {
    List result = null;
    try {
        final Session session = HibernateUtil.currentSession();
        session.connection().setReadOnly(true);
        result = session.createCriteria(CustomerDTO.class).add(Restrictions.eq("deleted", false)).add(Restrictions.eq("disabled", false)).list();

    } catch (HibernateException e) {
        e.printStackTrace();
    } catch (SQLException se) {
        se.printStackTrace();
    }
    return result;
}

public void add(final CustomerDTO obj) {
    try {
        final Session session = HibernateUtil.currentSession();
        session.connection().setReadOnly(false);
        obj.setCreationDate(new Date());
        obj.setLastEditDate(new Date());
        session.save(obj);                        
    } catch (HibernateException e) {
        e.printStackTrace();
    } catch (SQLException se) {
        se.printStackTrace();
    }
}

}

[/code]

HibernateUtil部分测试代码如下:
[code="java"]
public class HibernateUtil {

private static SessionFactory sessionFactory;
public static final String HIBERNATE_CONF_FILE = "hibernate.cfg.xml";

public static final ThreadLocal session = new ThreadLocal();
public static final ThreadLocal userTran = new ThreadLocal();   
public static String dialect;
static {
    try {           
        sessionFactory = getHibernateConfiguration().buildSessionFactory();

    } catch (Exception ex) {

    }
}

public static Configuration getHibernateConfiguration() {
Configuration config = new Configuration();
try {

        String path = null;

        path = "/hibernate_mapping/" + HIBERNATE_CONF_FILE;

        dialect = "org.hibernate.dialect." + "MySQL" + "Dialect";
        final Properties hibProperties = new Properties();
        hibProperties.setProperty(Environment.DIALECT, dialect);

         config.configure(path).addProperties(hibProperties);           
    } catch (Exception ex) {

    }   
    return config;
}

public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();

        session.set(s);
    }
    s.setFlushMode(FlushMode.AUTO);
    return s;
}

}
[/code]

请帮忙看一下问题所在.

  • 写回答

5条回答 默认 最新

  • qingfengyang_1 2009-07-16 10:54
    关注

    这个问题我详细的分析过,多数据源和多connection是两个选择,如果是多数据源,那么请求中应该包含一个信息,那就是数据是否是select or not,否则很难判断一个请求是用哪个数据源。多数据源如果不考虑这个问题混用的话很容易出现问题,因为master-slave之间是有延迟的,而且有很大的延迟。1分钟很正常。

    关于多connection,我也分析过,多connection情况在spring+hibernate的环境中有bug。

    第一次分析:
    http://ahuaxuan.iteye.com/blog/205926

    第二次分析(该文中包含了我对多数据源方式的看法)
    http://ahuaxuan.iteye.com/blog/323370

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 MATLAB动图的问题
  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名