day36 09-Hibernate中的事务:事务处理


什么是丢失更新呢?有一条数据你查出来了,查出来之后有一个事务A和一个事务B也都过来操作同一个记录。A拿到这条记录之后可能改它的某一个值了,B拿到这条记录之后改它的另外一个值。这个时候A事务提交已经提交到数据库了,假设A改的是工资已经提交到数据库了。如果B事务回滚,将A提交的数据覆盖了;或者是B提交事务也会将A事务提交的数据覆盖掉。所以不论另一个事务是提交还是回滚都会导致丢失更新。

两种办法解决丢失更新:悲观锁或者是乐观锁。

数据库的一种锁机制叫做排它锁。就是你A一查询的时候,B操作不了这条记录,不能查看。并且得等A的事务结束以后,释放排它锁之后B才能去操作。

乐观锁:加一个字段(版本号)。这个版本号每一次操作的时候都会自增。假设A已经修改了,已经修改了之后它会跟数据库比对这个版本号。如果一致才能修改,不一致无法修改。另一个事务进来之后如果有人修改的话这个版本号就会发生变化。那你这两不一样它就不允许你修改。


hibernate除了解决了读的问题,丢失更新也提供了解决方案。它里面就提供了悲观锁和乐观锁的解决方案。除了可以解决三种读的问题之外,还可以解决丢失更新的问题。悲观锁和乐观锁的问题用JDBC解决肯定要自己手写代码。hibernate里面已经帮你完成这些事情了。

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <!-- 必须去配置的属性 -->
    <!-- 配置数据库连接的基本信息: -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <property name="hibernate.connection.url"><!-- 连接的数据库是hibernate3_day02 -->
        jdbc:mysql:///hibernate3_day03
    </property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <!-- Hibernate的方言 -->
    <!-- 生成底层SQL不同的 -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>

    <!-- 可选的属性 -->
    <!-- 显示SQL -->
    <property name="hibernate.show_sql">true</property>
    <!-- 格式化SQL -->
    <property name="hibernate.format_sql">true</property>

    <property name="hibernate.connection.autocommit">false</property>
    <!-- hbm:映射 to DDL: create drop alter -->
    <property name="hibernate.hbm2ddl.auto">update</property>

    <!-- C3P0连接池设定-->
    <!-- 使用c3po连接池  配置连接池提供的供应商-->
    <property name="connection.provider_class">
        org.hibernate.connection.C3P0ConnectionProvider
    </property>

    <!--在连接池中可用的数据库连接的最少数目 -->
    <property name="c3p0.min_size">5</property>
    <!--在连接池中所有数据库连接的最大数目  -->
    <property name="c3p0.max_size">20</property>
    <!--设定数据库连接的过期时间,以秒为单位,
        如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
    <property name="c3p0.timeout">120</property>
    <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
    <property name="c3p0.idle_test_period">3000</property>
    
    <!-- 
        1-Read uncommited isolation
        2-Read commmitted isolation   oracle默认是2
        4-Repeatable read isolation   mysql默认是4
        8-Serializable isolation
     -->
    <property name="hibernate.connection.isiolation">4</property>
    
    <!-- 通知Hibernate加载那些映射文件 -->
    <!--     <mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" />
        <mapping resource="cn/itcast/hibernate3/demo2/Customer.hbm.xml" />
        <mapping resource="cn/itcast/hibernate3/demo2/Order.hbm.xml" />
        <mapping resource="cn/itcast/hibernate3/demo1/Book.hbm.xml" /> -->
    <!-- 把映射文件中的这几个都拿掉  重新把它引入  -->
    <mapping resource="cn/itcast/vo/Customer.hbm.xml" />
    <mapping resource="cn/itcast/vo/Order.hbm.xml" />


</session-factory>
</hibernate-configuration>
原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6702653.html