测试1:openSession正正在不开启事务的情况下执行操作

  Session session= SessionFactoryUtil.openSession();

   (1):session.get(UserInfo.class,14L);  //执行成功,得到数据

  (2):session.delete(new UserInfo(16L));  //执行成功 但数据库数据不变(符合逻辑)

   session.close();

   追溯了下源码发现:

  正正在不开启事务的情况下,session得到数据库结合是正正在执行查询语句的时候从结合池中获得。

Java代码
  1. private PreparedStatement getPreparedStatement(  
  2.             final Connection conn,  
  3.             String sql,  
  4.             boolean scrollable,  
  5.             final boolean useGetGeneratedKeys,  
  6.             final String[] namedGeneratedKeys,  
  7.             final ScrollMode scrollMode,  
  8.             final boolean callable)   

       正正在调用这个方法时传入了从结合池中拿到的结合。

  正正在执行完数据操作后调用

  afterOperation(boolean success);

  发现是非事务型的session直接调用

   connectionManager.aggressiveRelease();

  开释结合。

  测试2:getCurrentSession()正正在不开启事务的情况下执行操作

  Session session= SessionFactoryUtil.getCurrentSession();

   (1):session.get(UserInfo.class,14L);   //扔出分外get is not valid without active transaction

   (2):session.delete(new UserInfo(16L));// 扔出分外get is not valid without active transaction

  //session.close();  //线程绑定session会自动封合

  说明: 线程绑定session必须开启事务,此时的session曾经加载了拦截器,正正在执行数据操作时必须正正在活动的事务范围中。

  测试3:openSession正正在开启事务的情况下执行操作

  Session session= SessionFactoryUtil.openSession();

  session.getTransaction().begin();

   (1):session.get(UserInfo.class,14L);  //执行成功,得到数据

  (2):session.delete(new UserInfo(16L));  //执行成功

  session.getTransaction().commit();

   session.close();  //如若装备hibernate.transaction.auto_close_session=true可省去

  分解:

   (a):session.getTransaction().begin()-->Transaction result = getTransaction()

  -->result.begin()-->jdbcContext.connection()

  {

  if ( owner.isClosed() ) {

  throw new SessionException( "Session is closed" );

  }

  return connectionManager.getConnection();

  }

   睹到connectionManager有点熟习了吧,这就是牵制数据库结合的结合池.

  (b):session.getTransaction().commit()-->connectionManager.aggressiveRelease() 开释结合。

   此时的数据库结合是正正在准备开启事务的时获得,事务提交的时候开释结合。

  测试4:getCurrentSession()正正在开启事务的情况下执行操作

  Session session= SessionFactoryUtil.getCurrentSession();

  session.getTransaction().begin();

   (1):session.get(UserInfo.class,14L);        //执行成功

  (2):session.delete(new UserInfo(16L));   //执行成功

   session.getTransaction().commit();

  说明: 线程绑定session曾经加载了拦截器,提交的时候开释结合封合session。

  总结:

   (1)openSession()得到得session可以正正在显式开启事务的情况中运用,也可以正正在不开启事务的情况中运用(进行查询);getCurrentSession()必须正正在显式开启事务情况中运用。

  (2)openSession()是否显式开启事务决定了session得到结合的时机折柳。不开启事务的情况下数据库结合是正正在创建Statement时获得。于是正正在装备二级缓存的情况get()对象时,如果二级缓存中有需要的对象时,不会占用数据库结合。相反开启事务的情况下,无论二级缓存中是否有对象,众会占用数据库结合。

   (3)getCurrentSession()总会占用数据库结合。

除非特别注明,鸡啄米文章均为原创
转载请标明本文地址:http://www.sygjbus.cn/software/754.html
2017年8月17日
作家:鸡啄米 分类:软件开发 浏览: 评论:0