• 数据库的事物隔离级别以及锁的一些个人理解


    数据库的 基本分为 共享锁和排它锁

    排它锁顾名思义,不能和其他任何所共存。

    以SqlServer中某一行数据为例,

    特殊的,WithNoLock 这个是不给数据加上任何锁,所以根本和锁没关系

    再说update,update的过程是给这条数据加上排它锁,所以当另外事物过来要求修改这条数据的时候,会由于排它锁的互斥,导致无法申请到排它锁,从而实现同一时间只有一个事物对同一条数据进行修改。同样当该条数据正在修改中但其所属的事物还未提交的时候,查询需要在这条数据上加上共享锁的过程也由于排它锁的存在导致被阻塞。只有当修改的操作完成并且其所在事物提交以后,其他需要在该数据上加锁的操作才能进行下去。

    最后说 select ,一般的select 是直接给数据加上一个共享锁,其他的事物中的select 由于这条数据将是存在共享锁的原因,所以可以在多个事物中查询同一条数据。

    说到锁自然要提到数据库事物隔离级别 

    各种隔离级别就是通过锁来实现,

    以sqlserver为例,

    read uncommited

    直接可以当作WithNoLock 理解了

    read commited

    事物1 select该数据时加上共享锁,读完该共享锁立即释放。此时事物2中的update操作可以正常给该条数据加上排它锁并执行,若此时事物1再次select 该数据会发现该数据已经改变(由于事物2已经改变了该数据) ,这也就是所谓的脏读。所以 read commited 有脏读的风险。

    repeatable read

    事物1 select该数据时加上共享锁,但是直到事物完成该共享锁才释放,所以在事物1执行过程中,事物2过来想要update该条数据,都由于update需要加上排它锁,而和事物1的共享锁冲突,导致update被阻塞。这就避免了脏读的问题。但是如果事物2仅仅是select 且 事物1 没有update,那么是可以被读取的。且如果事物2新增一条数据。那么事物1的select 有可能读到的数据比原来多。这种情况被称为幻读,所以 repeatable read 有幻读的风险。

    serializable

    为了解决幻读的情况,把整个表都锁住,在事物1执行的时候,事物2连新增删除都不允许。

    再说说delete 首先update 的过程其实是先新增再删除,这点可以从触发器中看出来。所以update是独占锁也就是说明了delete 也是独占锁。所以delete 的情况可以当作update 来理解。

  • 相关阅读:
    projecthashing
    Windows 环境 gRPC环境搭建
    gitlab 适配性问题
    对 Golang 简洁架构实战的理解,以及 Golang 开源项目包定义的解惑
    Golang 关于百分比,小数点为数的问题
    Golang net/http 库日常 http 请求操作
    解决mysql建立事件时出现 “Cannot proceed because system tables used by Event Scheduler were found damaged at server start” 的错误
    如何在Linux安装Wine
    Public key for *.rpm is not installed
    从 IClassFactory 为 CLSID 为 {AA40D1D6CAEF4A56B9BBD0D3DC976BA2} 的 COM 组件创建实例失败,原因是出现以下错误: c001f011。
  • 原文地址:https://www.cnblogs.com/fengxiaoling/p/7794794.html
Copyright © 2020-2023  润新知