多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > Hibernate深入理解----03操作Session緩存方法(flush、refresh、clear,事務(wù)隔離級別)

Hibernate深入理解----03操作Session緩存方法(flush、refresh、clear,事務(wù)隔離級別)

來源:程序員人生   發(fā)布時間:2016-11-16 08:10:21 閱讀次數(shù):3866次

參考代碼下載github:https://github.com/changwensir/java-ee/tree/master/hibernate4

    Session 接口是 Hibernate 向利用程序提供的操縱數(shù)據(jù)庫的最主要的接口, 它提供了基本的保存, 更新, 刪除和加載 Java 對象的方法.
    Session 具有1個緩存, 位于緩存中的對象稱為持久化對象, 它和數(shù)據(jù)庫中的相干記錄對應(yīng). Session 能夠在某些時間點, 依照緩存中對象的變化來履行相干的 SQL 語句, 來同步更新數(shù)據(jù)庫, 這1進程被稱為刷新緩存(flush)
    站在持久化的角度, Hibernate 把對象分為 4 種狀態(tài): 持久化狀態(tài), 臨時狀態(tài), 游離狀態(tài), 刪除狀態(tài). Session 的特定方法能使對象從1個狀態(tài)轉(zhuǎn)換到另外一個狀態(tài)

測試用的init,before初始,結(jié)束方法請參考上篇文章http://blog.csdn.net/ochangwen/article/details/52575246

1、Session緩存

    在 Session 接口的實現(xiàn)中包括1系列的 Java 集合, 這些 Java 集合構(gòu)成了 Session 緩存. 只要 Session 實例沒有結(jié)束生命周期, 且沒有清算緩存,則寄存在它緩存中的對象也不會結(jié)束生命周期
    Session 緩存可減少 Hibernate 利用程序訪問數(shù)據(jù)庫的頻率。

@Test public void testSessionCache(){ News news = (News) session.get(News.class, 1); System.out.println(news); News news2 = (News) session.get(News.class, 1); System.out.println(news2); //只發(fā)了1條select語句 System.out.println(news == news2); //true }

2、操作Session緩存


2⑴.flush

/** * flush(): 使數(shù)據(jù)表中的記錄和 Session 緩存中的對象的狀態(tài)保持1致. 為了保持1致, 則可能會發(fā)送對應(yīng)的 SQL 語句. * 1. 在 Transaction 的 commit() 方法中: 先調(diào)用 sessionPojo 的 flush 方法(隱式flush), 再提交事務(wù) * 2. 顯示flush() 方法會可能會發(fā)送 SQL 語句, 但不會提交事務(wù)!!! * * 3. 注意: 在未提交事務(wù)或顯式的調(diào)用 sessionPojo.flush() 方法之前, 也有可能會進行 flush() 操作. * 1). 履行 HQL 或 QBC 查詢, 會先進行 flush() 操作, 以得到數(shù)據(jù)表的最新的記錄 * 2). 例外的情況:若記錄的 ID 是由底層數(shù)據(jù)庫使用自增的方式生成的, * 則在調(diào)用 save() 方法時, 就會在commit前!!立即發(fā)送 INSERT 語句. * 由于 save 方法后, 必須保證對象的 ID 是存在的! */ @Test public void testSessionFlush2(){ //在commit提交前發(fā)送1條Insert語句, News news = new News("Java", "SUN", new Date()); session.save(news); } @Test public void testSessionFlush(){ News news = (News) session.get(News.class, 1); //這里會履行1條select語句 //這里會先flush,然后會履行1條update語句(默許履行update語句),但沒有提交事務(wù) news.setAuthor("Oracle"); // sessionPojo.flush(); //顯示使用flush //HQL查詢,會履行flush,然后發(fā)送update語句 ,但到這里還沒提交事務(wù) News news2 = (News) session.createCriteria(News.class).uniqueResult(); System.out.println(news2); }

    flush:Session 依照緩存中對象的屬性變化來同步更新數(shù)據(jù)庫
    默許情況下 Session 在以下時間點刷新緩存:
      - 顯式調(diào)用 Session 的 flush() 方法
      - 當(dāng)利用程序調(diào)用 Transaction 的 commit()方法的時, 該方法先 flush ,然后在向數(shù)據(jù)庫提交事務(wù)
      - 當(dāng)利用程序履行1些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已產(chǎn)生了變化,會先 flush 緩存,以保證查詢結(jié)果能夠反應(yīng)持久化對象的最新狀態(tài)
    flush 緩存的例外情況: 如果對象使用 native 生成器生成 OID, 那末當(dāng)調(diào)用 Session 的 save() 方法保存對象時, 會立即履行向數(shù)據(jù)庫插入該實體的 insert 語句.
    commit() 和 flush() 方法的區(qū)分:flush 履行1系列 sql 語句,但不提交事務(wù);commit 方法先調(diào)用flush() 方法,然后提交事務(wù). 意味著提交事務(wù)意味著對數(shù)據(jù)庫操作永久保存下來。



2⑵.reflush

/** * refresh(): 會強迫發(fā)送 SELECT 語句, 以使 Session 緩存中對象的狀態(tài)和數(shù)據(jù)表中對應(yīng)的記錄保持1致! */ @Test public void testRefresh(){ //這個對象數(shù)據(jù)庫存在 News news = (News) session.get(News.class, 1); System.out.println(news); /*如果沒有refresh方法,當(dāng)程序運行到這里時,如果數(shù)據(jù)庫的內(nèi)容被修改(如調(diào)試時到這里時強迫修改數(shù)據(jù)庫的內(nèi)容) 輸出的內(nèi)容與上面的1樣,沒有得到最新的數(shù)據(jù)!!*/ //sessionPojo.flush(); //這里不會發(fā)送select語句 session.refresh(news); //這里會強迫發(fā)送select語句 System.out.println(news); }
如果使用了refresh,得到的兩個結(jié)果還是1樣,說明是使用了mysql的默許隔離級別“可重復(fù)讀”,修改成“讀已提交”測試就行

2⑶.clear

/** * 操作 Session 緩存有3個方法:flush()、refresh()、clear() */ /** * clear(): 清算緩存 */ @Test public void testClear(){ News news1 = (News) session.get(News.class, 1); session.clear(); News news2 = (News) session.get(News.class, 1); //會有兩條select語句,如果沒有clear方法,只會發(fā)送1條語句 }

2⑷.數(shù)據(jù)庫的隔離級別

    對同時運行的多個事務(wù), 當(dāng)這些事務(wù)訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機制, 就會致使各種并提問題:
      1).臟讀: 對兩個事物 T1, T2, T1 讀取了已被 T2 更新但還沒有被提交的字段. 以后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的.
      2).不可重復(fù)讀: 對兩個事物 T1, T2, T1 讀取了1個字段, 然后 T2 更新了該字段. 以后, T1再次讀取同1個字段, 值就不同了.
      3).幻讀: 對兩個事物 T1, T2, T1 從1個表中讀取了1個字段, 然后 T2 在該表中插入了1些新的行. 以后, 如果 T1 再次讀取同1個表, 就會多出幾行.
    數(shù)據(jù)庫事務(wù)的隔離性: 數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務(wù)的能力, 使它們不會相互影響, 避免各種并提問題.
    1個事務(wù)與其他事務(wù)隔離的程度稱為隔離級別. 數(shù)據(jù)庫規(guī)定了多種事務(wù)隔離級別, 不同隔離級別對應(yīng)不同的干擾程度, 隔離級別越高, 數(shù)據(jù)1致性就越好, 但并發(fā)性越弱

    Oracle 支持的 2 種事務(wù)隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默許的事務(wù)隔離級別為: READ COMMITED
    Mysql 支持 4 中事務(wù)隔離級別. Mysql 默許的事務(wù)隔離級別為: REPEATABLE READ
設(shè)置隔離級別
1).在 MySql 中設(shè)置隔離級別

    每啟動1個 mysql 程序, 就會取得1個單獨的數(shù)據(jù)庫連接. 每一個數(shù)據(jù)庫連接都有1個全局變量 @@tx_isolation, 表示當(dāng)前的事務(wù)隔離級別. MySQL 默許的隔離級別為 Repeatable Read
  查看當(dāng)前的隔離級別: SELECT @@tx_isolation;
  設(shè)置當(dāng)前 mySQL 連接的隔離級別:  
    set transaction isolation level read committed;
  設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別:
     set global transaction isolation level read committed;
2).在 Hibernate 中設(shè)置隔離級別
JDBC 數(shù)據(jù)庫連接使用數(shù)據(jù)庫系統(tǒng)默許的隔離級別. 在 Hibernate 的配置文件中可以顯式的設(shè)置隔離級別. 每個隔離級別都對應(yīng)1個整數(shù):
  1. READ UNCOMMITED
  2. READ COMMITED
  4. REPEATABLE READ
  8. SERIALIZEABLE
Hibernate 通過為 Hibernate .cfg.xml映照文件指定 hibernate.connection.isolation 屬性來設(shè)置事務(wù)的隔離級別
<property name="connection.isolation">2</property>


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 久久亚洲不卡一区二区 | 午夜免费啪在线观看视频网站 | 一区二区三区在线 | 网站 | 91嫩草私人成人亚洲影院 | 久久精品国产亚洲网址 | 亚洲福利精品 | 青青青青手机在线视频观看国产 | 成人小视频在线免费观看 | 波多野结衣欧美 | 国产午夜免费一区二区三区 | 亚洲精品亚洲九十七页 | 国产精品成人观看视频网站 | 一级中文字幕乱码免费 | 老黄网站在线观看免费 | 欧美操美女 | 免费麻豆国产一区二区三区四区 | 在线观看欧洲成人免费视频 | 日本wwwwwwwww | www.中文字幕在线观看 | 日韩一本二本 | 国产一区精品 | 欧美日韩一 | 99精品日韩 | 精品伊人久久久香线蕉 | 免费看亚洲 | 午夜肉伦伦影院在线观看 | 99久久这里只精品麻豆 | 亚洲69av | 欧美激情一区二区三区在线 | 国内精品视频成人一区二区 | 国产在线伊人 | 欧美精品综合 | 亚洲图片欧美小说 | 国外处破女一区二区 | 久久99久久99精品免观看麻豆 | 羞羞色院91蜜桃在线观看 | 国语精品视频在线观看不卡 | 日韩一级a毛片欧美区 | 成人久久久久久 | 亚洲成人高清 | 在线欧美三级 |