Hibernate學(xué)習(xí)筆記 - 第005天

服務(wù)器優(yōu)化

1.緩存 用空間換時(shí)間
2.能夠稍后做的操作都推遲做,不要馬上處理 用消息隊(duì)列 等服務(wù)器空閑,再一個(gè)個(gè)取出來解決

事務(wù)

事務(wù)的ACID

  • 原子性(Atomic):事務(wù)中各項(xiàng)操作,要么全做要么全不做,任何一項(xiàng)操作的失敗都會(huì)導(dǎo)致整個(gè)事務(wù)的失敗;
  • 一致性(Consistent):事務(wù)結(jié)束后系統(tǒng)狀態(tài)是一致的;
  • 隔離性(Isolated):并發(fā)執(zhí)行的事務(wù)彼此無法看到對(duì)方的中間狀態(tài);
  • 持久性(Durable):事務(wù)完成后所做的改動(dòng)都會(huì)被持久化,即使發(fā)生災(zāi)難性的失敗。通過日志和同步備份可以在故障發(fā)生后重建數(shù)據(jù)。

補(bǔ)充:關(guān)于事務(wù),首先需要知道的是,只有存在并發(fā)數(shù)據(jù)訪問時(shí)才需要事務(wù)。當(dāng)多個(gè)事務(wù)訪問同一數(shù)據(jù)時(shí),可能會(huì)存在5類問題,包括3類數(shù)據(jù)讀取問題(臟讀、不可重復(fù)讀和幻讀)和2類數(shù)據(jù)更新問題(第1類丟失更新和第2類丟失更新)。

臟讀(Dirty Read):A事務(wù)讀取B事務(wù)尚未提交的數(shù)據(jù)并在此基礎(chǔ)上操作,而B事務(wù)執(zhí)行回滾,那么A讀取到的數(shù)據(jù)就是臟數(shù)據(jù)。

時(shí)間 轉(zhuǎn)賬事務(wù)A 取款事務(wù)B
T1 開始事務(wù)
T2 開始事務(wù)
T3 查詢賬戶余額為1000元
T4 取出500元余額修改為500元
T5 查詢賬戶余額為500元(臟讀)
T6 撤銷事務(wù)余額恢復(fù)為1000元
T7 匯入100元把余額修改為600元
T8 提交事務(wù)

不可重復(fù)讀(Unrepeatable Read):事務(wù)A重新讀取前面讀取過的數(shù)據(jù),發(fā)現(xiàn)該數(shù)據(jù)已經(jīng)被另一個(gè)已提交的事務(wù)B修改過了。

時(shí)間 轉(zhuǎn)賬事務(wù)A 取款事務(wù)B
T1 開始事務(wù)
T2 開始事務(wù)
T3 查詢賬戶余額為1000元
T4 查詢賬戶余額為1000元
T5 取出100元修改余額為900元
T6 提交事務(wù)
T7 查詢賬戶余額為900元(不可重復(fù)讀)

幻讀(Phantom Read):事務(wù)A重新執(zhí)行一個(gè)查詢,返回一系列符合查詢條件的行,發(fā)現(xiàn)其中插入了被事務(wù)B提交的行。

時(shí)間 轉(zhuǎn)賬事務(wù)A 取款事務(wù)B
T1 開始事務(wù)
T2 開始事務(wù)
T3 統(tǒng)計(jì)總存款為10000元
T4 新增一個(gè)存款賬戶存入100元
T5 提交事務(wù)
T6 再次統(tǒng)計(jì)總存款為10100元(幻讀)

第1類丟失更新:事務(wù)A撤銷時(shí),把已經(jīng)提交的事務(wù)B的更新數(shù)據(jù)覆蓋了。

時(shí)間 轉(zhuǎn)賬事務(wù)A 取款事務(wù)B
T1 開始事務(wù)
T2 開始事務(wù)
T3 查詢賬戶余額為1000元
T4 查詢賬戶余額為1000元
T5 匯入100元修改余額為1100元
T6 提交事務(wù)
T7 取出100元將余額修改為900元
T8 撤銷事務(wù)
T9 余額恢復(fù)為1000元(丟失更新)

第2類丟失更新:事務(wù)A覆蓋事務(wù)B已經(jīng)提交的數(shù)據(jù),造成事務(wù)B所做的操作丟失。

時(shí)間 轉(zhuǎn)賬事務(wù)A 取款事務(wù)B
T1 開始事務(wù)
T2 開始事務(wù)
T3 查詢賬戶余額為1000元
T4 查詢賬戶余額為1000元
T5 取出100元將余額修改為900元
T6 提交事務(wù)
T7 匯入100元將余額修改為1100元
T8 提交事務(wù)
T9 查詢賬戶余額為1100元(丟失更新)

數(shù)據(jù)并發(fā)訪問所產(chǎn)生的問題,在有些場(chǎng)景下可能是允許的,但是有些場(chǎng)景下可能就是致命的,數(shù)據(jù)庫通常會(huì)通過鎖機(jī)制來解決數(shù)據(jù)并發(fā)訪問問題,按鎖定對(duì)象不同可以分為表級(jí)鎖和行級(jí)鎖;按并發(fā)事務(wù)鎖定關(guān)系可以分為共享鎖和獨(dú)占鎖,具體的內(nèi)容大家可以自行查閱資料進(jìn)行了解。
直接使用鎖是非常麻煩的,為此數(shù)據(jù)庫為用戶提供了自動(dòng)鎖機(jī)制,只要用戶指定會(huì)話的事務(wù)隔離級(jí)別,數(shù)據(jù)庫就會(huì)通過分析SQL語句然后為事務(wù)訪問的資源加上合適的鎖,此外,數(shù)據(jù)庫還會(huì)維護(hù)這些鎖通過各種手段提高系統(tǒng)的性能,這些對(duì)用戶來說都是透明的(就是說你不用理解,事實(shí)上我確實(shí)也不知道)。ANSI/ISO SQL 92標(biāo)準(zhǔn)定義了4個(gè)等級(jí)的事務(wù)隔離級(jí)別,如下表所示:

隔離級(jí)別 臟讀 不可重復(fù)讀 幻讀 第一類丟失更新 第二類丟失更新
READ UNCOMMITED 允許 允許 允許 不允許 允許
READ COMMITTED 不允許 允許 允許 不允許 允許
REPEATABLE READ 不允許 不允許 允許 不允許 不允許
SERIALIZABLE 不允許 不允許 不允許 不允許 不允許

需要說明的是,事務(wù)隔離級(jí)別和數(shù)據(jù)訪問的并發(fā)性是對(duì)立的,事務(wù)隔離級(jí)別越高并發(fā)性就越差。所以要根據(jù)具體的應(yīng)用來確定合適的事務(wù)隔離級(jí)別,這個(gè)地方?jīng)]有萬能的原則。

連接池

c3p0

  • 導(dǎo)入jar包
    c3p0-0.9.5.2.jar
    hibernate-c3p0-5.2.8.Final.jar
    mchange-commons-java-0.2.11.jar
  • hibernate.cfg.cml配置
        <!-- c3p0 connection pool -->
        <property name="c3p0.min_size">10</property>
        <property name="c3p0.max_size">100</property>
        <property name="c3p0.timeout">60</property>
        <property name="c3p0.acquire_increment">20</property>
        <property name="c3p0.initialPoolSize">20</property>

dataSource


二級(jí)緩存

hibernate.cfg.xml配置

        <!-- Disable the second-level cache  -->
        <property name="cache.use_second_level_cache">true</property>
        <property name="cache.region.factory_class">
            org.hibernate.cache.ehcache.EhCacheRegionFactory
        </property>

ehcache.xml配置

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="300"
        overflowToDisk="true"
        />
    <cache name="hello"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
    <cache name="goodbye"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> 
</ehcache>

注解

@Cache(region = "hello", usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容