常见的几种数据锁总结

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 常见的几种数据锁总结,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

  • 代码中:比如多个线程需要同时操作修改共享变量,这时需要给变量上把锁(syncronized),保证变量值是对的。
  • 数据库表:当多个用户修改表中同一数据时,我们可以给该行数据上锁(行锁)。

1.悲观锁(悲观并发控制)

  • 当我们要对数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发的发生。
  • 对数据的修改抱有悲观态度的并发控制方式。我们一般认为数据被并发修改的概率比较大,所以需要在修改之前先加锁
  • 数据库中的行锁,表锁,读锁,写锁,以及 syncronized 实现的锁均为悲观锁。

2.乐观锁(并发类型的锁)

  • 乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁,只有到数据提交的时候才通过一种机制来验证数据是否存在冲突。

  • 乐观锁通常是通过在表中增加一个版本(version)或时间戳(timestamp)来实现,其中,版本最为常用。

3.悲观锁实现

  • 利用悲观锁的解决思路是,我们认为数据修改产生冲突的概率比较大,所以在更新之前,我们显示的对要修改的记录进行加锁,直到自己修改完再释放锁。加锁期间只有自己可以进行读写,其他事务只能读不能写。
  • 线程 A 下单前先给这行数据(id=C001)加上悲观锁(行锁)。怎么样给这行数据加上悲观锁呢?当然是在select给这行数据加上锁
select num from commodity where id = C001 for update
手动加悲观锁:读锁LOCK tables test_db read
释放锁UNLOCK TABLES;
写锁:LOCK tables test_db WRITE
释放锁UNLOCK TABLES;

4.乐观锁解实现

  • 乐观锁是通过版本号 version 来实现的。所以,我们需要给 TableName表加上 version 字段。
update TableName set Name=lisi,version=version+1 where ID=#{id} and version=#{version}

5.如何选择

  • 乐观锁适用于读多写少的场景,可以省去频繁加锁、释放锁的开销,提高吞吐量
  • 在写比较多的场景下,乐观锁会因为版本不一致,不断重试更新,产生大量自旋(会导致大量的请求冲突),消耗 CPU,影响性能。这种情况下,适合悲观锁

6.更新锁

  • 更新锁定是共享锁定和排他锁定的混合。共享锁是在DML执行之前进行更改之前使用的。其他事务可以读取锁定的数据,但不能修改它。一旦修改开始,它就成为一个排他锁,其他事务直到事务结束后才能读取和更新锁定的数据
  • 更新锁可以避免造成死锁。同一时间只有一个更新锁可以锁定数据,类似于排他锁
  • 但不同之处在于,更新锁只能锁定自身,而不能修改底层数据。在修改数据之前,可以将它转换为排他锁,这可以通过提示UPDLOCK更新锁来实现

7.共享锁

  • 共享锁在数据读取悲观(慢节奏)并行持有。共享锁操作的同时保持其他事务可访问,但不修改锁定的数据。除非事务是通过提示符(READCOMMITTED, READCOMMITTEDLOCK)或隔离级别等于或大于可重复读(Repeatable READ)完成的,否则锁定的数据将在共享锁READ完成后被释放。
  • 在一般情况下,您不会看到共享锁,因为SELECT在系统运行期间释放了锁。dm_tran_locks命令选择。这就是为什么需要额外的提示来查看锁的类型。

8.排他锁(eXclusive locks)

  • 排他锁定用于修改数据并防止其他事务被修改的事务中。您只能通过NOLOCK的提示读取锁定的数据或未确认的隔离级别数据。SQL Server在修改数据时使用独占锁定。
  • 锁定其他事务的请求将被拒绝,直到事务关闭。一个资源只能有一个排他锁。当一个事务持有资源上的排他锁时,其他事务无法读取该资源。因此,这个锁限制了并发行数。

9.意图锁定(Intent locks)

  • 有意锁定意味着当一个事务通知另一个事务时,它有锁定数据的“意图”,所以它就像名称一样。它确保事务获得要修改的正确数据,防止其他事务获得更高级别的锁。这意味着您打算在获得锁或表上的行之前锁定一个Page。这可以防止其他事务在表上放置排他锁并试图解锁行或页。包含锁定被放置在页和表上,以防止其他事务锁定数据。
  • IS和IX
  • 「意向共享锁(IS)」:事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
  • 「意向排他锁(IX)」:事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
  • 如果一个事务请求的锁模式与当前的锁兼容,InnoDB就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123955.html

(1)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!