疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

浅谈OpenSesssion和getCurrentSession及单例和多例模式


 

   

  之所以会有OpenSesssion() 和getCurrentSession()的区别,是因为session不是线程安全的,特别是多线程并发的时候更会导致数据混乱。

  这一点可以这样解释,OpenSesssion()打开线程操作。操作完成之后,关闭线程。也清除了数据,如果不关闭线程。则数据还没有清除,继续留在对象上面,后面的线程进行的数据操作必然与原来的残留的数据混乱,所以OpenSesssion()必须关闭线程。

  可是即使关闭了线程,还有安全问题,那就是在单线程操作未结束的时候突然有一个线程开始涌进来,也就是俗话说的多线程并发的情况。可是这个时候多线程的数据又混乱了。

  就好比读者君不小心在地上撒了一万块钱,作者君心思灵动,立马拿出来一千块钱也撒过去,然后咱们一块捡钱,你说同样的时间下,我能捡多少钱。就算长期码代码导致腿脚不灵活,想来三四千可以有吧,这也算赚的啊。

  这就是opensession为何必须关闭以及session线程不安全的原因。也是getCurrentSession()出现的原因。

  毕竟他是单例模式。所以为了解决数据混乱问题,采用多例模式解决并发问题。

  而sessionFactory是线程安全的。多个并发的线程可以同时访问一个sessionFactory并从中获取session实例,这也是为何封装的时候不会讲这两者封装到一块的原因。

  那么什么是单例模式与多例模式呢,其实可以这样理解,单例模式就是原件使用模式,多例模式就是复印件使用模式。

  如果原件使用,稍有损坏,就不能用了,但是用复印件使用,即使丢了,烧了,也无损继续使用,不过是通过原件再复印一分而已。

  那么具体到hibernate的session管理上就是threadLoacl模式解决方案。

  private static SessionFactory sessionFactory = null;

  //声明一个session类型的线程局部变量。

 

  private static final ThreadLocal tl = new ThreadLocal();

  //static代码块,安全的线程,每一次运行都必须加载。

  static {

  // 读取并解析配置文件,以及映射文件

  try {

  Configuration configuration = new Configuration().configure();

  // 测试

  System.out.println("成功");

  // 创建SessionFactory实例

  sessionFactory = configuration.buildSessionFactory();

  } catch (HibernateException e) {

  e.printStackTrace();

  }

  }

  public static Session getSession() {

  //先获得一个session

  Session session = tl.get();

  //没有现成的,就临时创建一个新的使用。

  if (session == null) {

  if (sessionFactory!=null) {

  //建一个新的session

  session = sessionFactory.openSession();

  tl.set(session);

  }

  }

  //有现成的直接拿来用。

  return session;

  }所以getCurrentSession()不必手动关闭session。会在提交或者回滚之后自动关闭。

  那么总结如下:

  OpenSesssion()不绑定线程,线程不安全,需手动关闭session。 getCurrentSession()绑定当前线程,线程安全,事务提交或者回滚之后自动关闭session。

  所以现如今,安全第一的情况下基本上淘汰了OpenSesssion()。推荐使用 getCurrentSession()。