如果有很多Server集群运行一个应用啊
1.
Hibernate的session如果并发持久化同一个对象,不会有问题吗?
2.
如果有第三方(比如为了业务需要,需要手工执行一段sql)操作了已经存放在session里的持久对象,不会有问题吗?
希望能帮助我啊

解决方案 »

  1.   

    请看下面这段代码:
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get(); if (session == null || !session.isOpen()) {
    if (sessionFactory == null) {
    rebuildSessionFactory();
    }
    session = (sessionFactory != null) ? sessionFactory.openSession()
    : null;
    threadLocal.set(session);
    }        return session;
        }
    它先创建一个私有的ThreadLocal,ThreadLocal是java中一种较为特殊的线程绑定机制.通过ThreadLocal存取的数据,总是与当前线程相关,也就是说,JVM为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制.
    ThreadLocal的独特地方,它会问每个线程维护一个私有的变量空间,实际上其原理是在JVM中维护一个Map,这个Map的key就是当前的线程对象,而value则是线程通过ThreadLocal.set方法保存的对象实例,当线程调用ThreadLocal.get方法时,ThreadLocal会根据当前线程对象的引用,取出Map中对应的对象返回.
      

  2.   

    还有要补充一下,你觉得要操作同一对象时会不会出错,这个你放心好了,Hibernate已经在事物性上面考虑过了.事物管理有原子性,一致性,隔离性和持久性.Hibernate把AutoCommit设置成false,所以要提交的时候要写Transaction tx=session.beginTransaction(),tx.commit().Hibernate支持两种锁机制,"悲观锁"和"乐观锁",它会对操作进行加锁的.就是数据加锁.从而不会发生脏读现象.
    我还是建议你去看下介绍Hibernate的书,在Hibernate高级特性里有说明的.因为这里一下说的很清楚是不可能的.只能这样了,有什么问题再说吧.
      

  3.   

    其实 sessoin 也是可以改造的,你可以存到远程的一台机器上面。集群应用要拿session可以到 session server上面获取。相当于分布式cache。当然如果你的集群负责均衡设备会根据session将一个会话始终保持连接在一台机器上面,那么就不会存在每个服务器上面持久化一个相同session的情况了。