從一個hibernate配置文件中瞭解到的東西

業務場景:java

      先展現一份hibernate配置文件,而後來詳細說裏面蘊含的東西。sql

<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
    <class name="cn.com.besttone.report.domain.ReportCompOrderDetail" table="REPORT_COMP_ORDER_DETAIL"
        dynamic-update="true" dynamic-insert="true" optimistic-lock="version" schema="BESTTONETICKET">
        <cache usage="nonstrict-read-write" />
         
        <id name="id" unsaved-value="null" type="java.lang.Long" column="ID" length="19">
            <generator class="sequence" >
                <param name="sequence">SEQ_REPORT_COMP_ORDER_DETAIL</param>
            </generator>
        </id>
 
         
        <property name="statusFlag" type="java.lang.String" column="STATUS_FLAG" />
        <property name="checkAccountStatus" type="java.lang.String" column="CHECK_ACC_STATUS" />
        <property name="checkAccountDate" type="java.util.Date" column="CHECK_ACC_DATE" />
        <property name="spWriteBackStatus" type="java.lang.String" column="SP_WRITE_BACK_STATUS" />
        <property name="dataSource" type="java.lang.String" column="DATA_SOURCE" />
        <property name="cpId" type="java.lang.Long" column="CPID" />
        <property name="cardType" type="java.lang.String" column="CARD_TYPE" />
        <property name="insuranceProvideCode" type="java.lang.String" column="INSURE_PROVIDER_CODE" />
    </class>
</hibernate-mapping>

在這裏主要分析xml裏面配置的屬性,咱們用的是oracle數據庫數據庫

schema:oracle的schema定義:A schema is a collection of database objects (used by a user.)。就是一個數據庫對象的集合,包括了tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links。一個用戶通常對應一個schema,該用戶的schema名等於用戶名,並做爲該用戶缺省schema。好比咱們在訪問數據庫時,訪問scott用戶下的emp表,經過select * from emp; 其實,這sql語句的完整寫法爲select * from scott.emp。因此相對而言,咱們在hibernate查詢數據的時候,能夠配置schema,也能夠不進行配置,由於schema,默認爲用戶名。併發

dynamic-update="true" dynamic-insert="true" :由於在hibernate幫我咱們生成實際的sql語句的時候,當屬性爲null,他也會生成對應的sql,若是咱們配置了這兩個屬性,就能夠只生成不爲null的屬性值,對應的有更新,和插入。oracle

例:update HBTEST set VAL1=?,VAL2=? where ID=?app

一樣的操做若是把設置爲true的話,sql語句只包含更新的字段:update HBTEST set VAL1=? where ID=?dom

optimistic-lock ide

悲觀鎖:一般是由數據庫機制實現的,在整個過程當中把數據鎖住(查詢時),只要事務不釋放(提交或回滾),任何用戶都不能查看和修改。高併發

當有一個方法經過悲觀鎖機制加載某個對象的時候,對這個對象進行了一系列的操做,在進行操做的時候,也就是隻要事務未提交,這個鎖就一直存在。當另一個方法加載這個對象的時候(兩個對象是一個對象,即惟一標示符的值是相同的)只會發出查詢語句,中止不動,由於,前一個方法使用了悲觀鎖機制加載的這個對象,並無結束事務(提交或回滾),所以這時是排他的。當第一個方法提交了事務,第二個方法才能夠加載成功並按照本身的意願執行其全部操做。.net

悲觀鎖的使用:悲觀鎖解決了更新丟失( lost update )問題,可是也帶來了併發問題 à 併發很差

樂觀鎖:

觀鎖其實不是一種鎖,也就不是鎖住的問題,而是給數據庫表加入了一個字段(可使版本號( version ),也可使一個時間戳( timestamp )),或是進行所有字段 / 髒數據字段比較(這種方式適合於之前遺留下來的系統,在不更改原來表結構的時候使用這種策略)來肯定數據是否被修改過,通常的應用是採用數據版本的方式( version )實現,在讀取數據的時候將 version 讀取出來,在保存數據的時候判斷 version 的值是否小於數據庫中的 version 的值,小於則不容許更新,不然能夠更新。

使用 version 實現樂觀鎖(推薦使用):在一個事務提交後就會更改數據庫,數據庫中 version 的值會自動加 1 。實現步驟 à 1 、在持久化類中加入 version 屬性,生成其 getter 和 setter 方法。 2 、在配置文件中的 <class> 標籤中配置一個屬性 optimistic-lock=」version」 (這個屬性的默認值就是 version ,能夠不進行配置,但建議配置上) 3 、對 version 字段進行映射,使用 version 標籤(這個字段的映射必須在 id 標籤的後面第一位) à <version  name=」version」/>

細節分析 à 在一個事務加載某個持久化類時,對這個對象進行了一系列操做,可是尚未提交事務,於此同時,另一個事物也加載了這個持久化類,並完成了一系列的操做後提交了事務,而後,第一個事務這時也要提交事務了,這樣就會拋出一個異常 à org.hibernate.StableObjectStateException:Rows was updated or deleted by another transaction… ,緣由是這樣的:當一個事務提交時會發出這樣一條 SQL 語句 à update 表名 set 全部表屬性 =? where id( 惟一標示符值 )=? andversion=? 這個語句中 version=? 是最關鍵的。以上說的那個例子中,第一個事務拿的是本身的舊的 version 值,進行更更新,而第二個事務在提交後,已經改變了 version ,變成了新的 version 值了,這樣第一個事務提交事務時發出的 update 表名 set 全部表屬性 =? where id( 惟一標示符值 ) =? and version=? 這條語句將會失敗!就會拋出以上異常信息。

樂觀鎖:適合於高併發。

相關文章
相關標籤/搜索