• 攻城狮在路上(壹) Hibernate(十七)--- Hibernate并发处理问题


    一、多个事务并发运行时的并发问题
      总结为第一类丢失更新、脏读、虚读、不可重复读、第二类丢失更新。
      1、第一类丢失更新: 撤销一个事务时,把其他事务已提交的更新数据覆盖。
      2、脏读: 一个事务读到另一个事务未提交的更新数据。
      3、虚读(幻读): 一个事务读到另一个事务已提交的新插入的数据。
      4、不可重复读: 一个事务读到另一个事务已提交的更新数据。
      5、第二类丢失更新: 这是不可重复读的特例,一个事务覆盖另一个事务已提交的更新数据。
    二、数据库系统的锁的基本原理
      数据库系统采用锁来实现事务的隔离性。
      1、锁的基本原理如下
        A、当一个事务访问某种数据库资源时,如果执行select语句,必须先获得共享锁;如果执行insert、update或者delete语句,必须获得独占锁。
        B、当第二个事务也要访问相同的资源时,如果执行select语句,也必须先获得共享锁;如果执行inert、update或者delete语句,也必须先获得独占锁。此时根据已经放置在资源上的锁的类型,来决定第二个事务应该等待还是立即获取该锁。
        第二个事务获取锁的情况说明:

    资源上已经放置的锁 第二个事务进行读操作 第二个事务进行更新操作
    立即获得共享锁 立即获得独占锁
    共享锁 立即获得共享锁 等待第一个事务解除共享锁
    独占锁 等待第一个事务解除独占锁 等待第一个事务解除独占锁


      2、锁的多粒度性及自动锁升级
        数据库系统能够锁定的资源包括:数据库、表、区域、页面、键值(指带有索引的行数据)、行。
        按照锁定资源的粒度,锁可以分为以下类型:
          A、数据库级锁:锁定整个数据库。
          B、表级锁:锁定一张数据库表。
          C、区域级锁:锁定数据库的特定区域。
          D、页面级锁:锁定数据库的特定页面。
          E、键值级锁:锁定数据库表中带有索引的一行记录。
          F、行级锁:锁定数据库表中的单行记录。
        锁的粒度越大,事务间的隔离性就越高,事务间的并发性能就越低。
        锁升级是指调整锁的粒度,将多个低粒度的锁替换成少数更高粒度的锁,以此来降低系统负荷。
      3、锁的类型和兼容性
        A、共享锁:
          共享锁用于读数据操作,它是非独占的,允许其他事务同时读取其锁定的资源,但是不允许其他事务更新它。
        B、独占锁:
          独占锁也叫排他锁,适用于修改数据的场合。它所锁定的资源,其他事务不能读取也不能修改。
        C、更新锁:
          更新锁在更新操作的初始化阶段用来锁定可能要被修改的资源,这样可以避免使用共享锁造成的死锁现象。
        共享锁、独占锁、更新锁的特征总结:

    特征项 共享锁 独占锁 更新锁
    加锁条件 当一个事务执行select语句时,数据库会为这个事务分配一个共享锁,来锁定被查询的数据。 事务执行inert、update、delete语句时,分配独占锁。 事务执行update语句时,分配更新锁
    解锁条件 一般数据被读取后,数据库系统立刻解除共享锁。当查询多条记录时,也是一条一条的锁定-解锁。 独占锁直到事务结束才能被解除。 数据读取完毕,执行更新操作时,会把更新锁升级为独占锁。
    与其他锁兼容性 如果数据资源上放置了共享锁,还能再放置共享锁和更新锁。 不能和其他锁兼容。 与共享锁兼容,但只能有一个更新锁,这样可以避免死锁
    并发性能 具有良好的并发性能 并发性能较差  


      4、死锁及其防治方法
        在数据库系统中,死锁是指多个事务分别锁定一个资源,又试图请求锁定对方已经锁定的资源,这就产生了一个锁定请求环,导致多个事务都处于等待对方释放锁定资源的状态。
        许多数据库系统能自动定期搜索和处理死锁问题,当检测到锁定请求环时,系统将结束死锁优先级最低的事务,并撤销该事务。
        避免死锁的方法:
          A、合理安排表访问顺序。
          B、使用短事务。
          C、如果对数据的一致性要求不是很高,可以允许脏读。
          D、如果可能的话,错开多个事务访问相同数据资源的时间,以防止锁冲突。
          E、使用尽可能低的事务隔离级别。

    三、数据库的隔离级别
      一般情况下,应首先考虑让数据库系统自动管理锁。
      数据库提供了4种事务隔离级别供用户选择:

    隔离级别 是否有第一类丢失更新 是否脏读 是否虚读 是否不可重复读 是否第二类丢失更新
    Serializable
    Repeatable Read
    Read Commited
    Read Uncommited


      1、在mysql.exe中设置隔离级别的相关语句

    select @@tx_isolation;
    set transaction isolation level read commited;
    set global transaction isolation level read commited;

      2、在应用程序中设置隔离级别
        在Hibernate配置文件中可一个显式配置:
        hibernate.connection.isolation=2
        1:Read Uncommited; 2:Read Commited; 4:Repeatable Read; 8:Serializabel

    四、在应用程序中使用悲观锁
      1、从应用程序的角度,锁可以分为2类
        A、悲观锁:指在应用程序中显式的为数据资源加锁。会影响并发性能。
        B、乐观锁:乐观锁假定当前事务操作数据资源时,不会有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁。
      2、悲观锁的实现方式
        A、在应用程序中显示指定采用数据库系统的独占锁来锁定数据源。
        B、通过在数据库表中增加一个标记字段,来判断事务是否可以访问。
      3、利用数据库系统的独占锁来实现悲观锁
        A、SQL语句控制:

    select .. for update;

        B、Hibernate中使用get()或者load()方法时:
          Account account = (Account)session.get(Account.class,new Long(1),LockMode.UPGRADE);
          LockMode不再深入介绍。

    五、利用Hibernate的版本控制来实现乐观锁
      基本的实现逻辑是:在数据库里定义一个表示版本的字段,或者一个时间戳字段,然后在映射文件中配置一个<version>元素,或者一个<timestamp>元素。
      暂时不做深入了解。

  • 相关阅读:
    LeetCode 123 Best Time to Buy and Sell Stock III
    直接选择排序算法汇总
    zoom:1是什么意思
    怎么去掉织梦网站首页带的index.html/index.php
    wamp apache无法启动的解决方法
    提交到svn服务器时,一直缓冲不,
    桌面上图标都不见了怎么办听语音
    如何清除网上浏览痕迹?清除缓存
    TortoiseSVN文件夹及文件图标不显示解决方法
    快捷键
  • 原文地址:https://www.cnblogs.com/tq03/p/3789434.html
Copyright © 2020-2023  润新知