从一个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=? 这条语句将会失败!就会抛出以上异常信息。

乐观锁:适合于高并发。

相关文章
相关标签/搜索