Hibernate Session缓存

Session缓存:

  在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期
  Session 缓存可减少 Hibernate 应用程序访问数据库的频率。

1:利用反射查询对象

News news =(News) session.get(News.class, 1);
        System.out.println(news);
        News news2 =(News) session.get(News.class, 1);
        System.out.println(news2);

但是只出现了一条SQL

这就是session缓存。也叫一级缓存。位于缓存中的数据叫做持久化对象。

站在持久化的角度。hibernate把对象分为4种状态:持久化。临时。游离。删除。

session缓存有三个方法。

1:flush()方法。

    它的作用:缓存中的数据对象与数据库中数据对象保持一致。会发送SQL语句。但是不会提交事务。

    为了确保数据一致。在以下会调用flush()方法。

      1:显示的调用。session.flush();

      2:事务提交的时候。会先调用flush()。然后再提交事务。

      3:执行HQL或QBC查询。

      4:若记录的ID是native(底层数据库自增的形式)生成的。在调用save()方法后。立即发送insert语句。

     commit()方法的源码:在AbstractTransaction类中。

 1 @Override
 2     public void commit() throws HibernateException {
 3         if ( localStatus != LocalStatus.ACTIVE ) {
 4             throw new TransactionException( "Transaction not successfully started" );
 5         }
 6 
 7         LOG.debug( "committing" );
 8 
 9         beforeTransactionCommit();
10 
11         try {
12             doCommit();
13             localStatus = LocalStatus.COMMITTED;
14             afterTransactionCompletion( Status.STATUS_COMMITTED );
15         }
16         catch ( Exception e ) {
17             localStatus = LocalStatus.FAILED_COMMIT;
18             afterTransactionCompletion( Status.STATUS_UNKNOWN );
19             throw new TransactionException( "commit failed", e );
20         }
21         finally {
22             invalidate();
23             afterAfterCompletion();
24         }
25     }

在12行提交事务。第9行是  beforeTransactionCommit();

在提交事务前干点什么?

在JdbcTransaction类中。

 1 protected void beforeTransactionCommit() {
 2         transactionCoordinator().sendBeforeTransactionCompletionNotifications( this );
 3 
 4         // basically, if we are the driver of the transaction perform a managed flush prior to
 5         // physically committing the transaction
 6         if ( isDriver && !transactionCoordinator().getTransactionContext().isFlushModeNever() ) {
 7             // if an exception occurs during flush, user must call rollback()
 8             transactionCoordinator().getTransactionContext().managedFlush();
 9         }
10 
11         if ( isDriver ) {
12             transactionCoordinator().getTransactionContext().beforeTransactionCompletion( this );
13         }
14     }

在第8行会管理事务。TransactionContext  类中

public void managedFlush();
SessionImpl  类中
1
public void managedFlush() { 2 if ( isClosed() ) { 3 LOG.trace( "Skipping auto-flush due to session closed" ); 4 return; 5 } 6 LOG.trace( "Automatically flushing session" ); 7 flush(); 8 }

在第7行进行flush()方法的调用。

2:refresh():强制使缓存中的一个对象状态与数据库中记录的对象状态一致。

 打上断点。然后现在去数据库中修改数据。

得到的数据还是一样的。

 

使用refresh()方法

 

 这是因为Hibernate在MySQL中的隔离级别。默认是可重复读。虽然重新读了一个select。但是还是读的以前的那个select语句。

在hibernate.cfg.xml中

1 <!-- 设置隔离级别 -->
2         <property name="connection.isolation">2</property>

1. READ UNCOMMITED  读未提交数据
2. READ COMMITED    读已提交数据
4. REPEATABLE READ  可重复读
8. SERIALIZEABLE    串行化

3:clear()  清理缓存

原文地址:https://www.cnblogs.com/bulrush/p/7783674.html