美文网首页Net
关于数据库锁机制

关于数据库锁机制

作者: Aneko | 来源:发表于2019-04-18 12:22 被阅读1次

书读百遍,不如 敲一遍代码...
先解释一下名词

共享锁(S):一般是Select 查询是自带共享锁;共享锁允许多个用户同时查询和修改(默认是这样,除非单独设置共享锁的生命周期,以下会说到);
排它锁(X):一般是Insert,Update,Delete时会自动加排它锁;

我们先看一个正常的例子:
一,
多个事务查询框模拟多个用户:

begin tran 
-- S锁
select * from users  where id= 1
--等待10秒
WaitFor DELAY '00:00:05'
commit;

begin tran 
update users set Name= 'ttttt3' where id = 1
commit;

此时:第二个事务查询框不受第一个查询框的影响,可以直接出数据;证明Select的共享锁在查询后直接就默认释放掉了;

二,
begin tran 
-- S锁
select * from users with(holdlock)  where id= 1
--等待10秒
WaitFor DELAY '00:00:05'
commit;

begin tran 
update users set Name= 'ttttt3' where id = 1
commit;

此时:第二个事务的更新操作受第一个事务的影响,需要等待5秒也就是第一个事务Commit的时候,才能执行;with(holdlock) 就是人为的提高了事务一Select共享锁的生命周期;

三,
begin tran 

update users set Name= 'tt' where id = 1
WaitFor DELAY '00:00:05'

commit;


begin tran 
-- S锁
select * from users  where id= 1

commit;

此时:第二个事务的更新或者查询操作受第一个事务的影响,需要等待5秒也就是第一个事务Commit的时候,才能执行;第一个事务的update操作添加了排它锁,只有等commit提交事务的时候才会释放;

四,
begin tran 

update users set Name= 'tt222' where id = 1
WaitFor DELAY '00:00:05'

commit;
--rollback

begin tran 
-- S锁
select * from users with(nolock)  where id= 1

commit;

此时:第二个事务者查询操作不受第一个事务的影响,可以直接出结果;但是第二个事物使用了with(nolock) 就是忽略锁的意思; 在第一个事务失败rollback的情况下可能会出现脏读的情况(第二个事物实际读取的是第一个事务的更新后的数据);

五,死锁
begin tran 

update users set Name= 'tt' 
WaitFor DELAY '00:00:05'
-- S锁
select * from uu with(holdlock)
commit;


begin tran 

update uu set Name= 'ttttt3' 
--WaitFor DELAY '00:00:50'
select * from users with(holdlock)
commit;

image.png

此时:
两个事务之间出现死锁; 事务一对users添加排它锁,并同时等待5秒钟; 事务二对uu 添加排它锁,并以(holdlock)方式 访问users表,但此时users排它锁并没有释放,所以无法添加共享锁,所以一直等待事务一释放排它锁;
此时事务一访问uu ,同样的uu排它锁并未释放,由此导致两个事务之间相互等待造成死锁;
死锁的造成方式还有很多种,总结就是对A中的A1添加了排它锁,在B中B1添加了排它锁,同时在A中访问B1,在B中访问A1,由此相互等待造成死锁;

最后附上锁类型:
HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,而不是在语句执行完立即释放所添加的锁。   
NOLOCK:不添加共享锁和排它锁,当这个选项生效后,可能读到未提交读的数据或“脏数据”,这个选项仅仅应用于SELECT语句。   
PAGLOCK:指定添加页锁(否则通常可能添加表锁)。  
READCOMMITTED用与运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下,SQL Server 2000 在此隔离级别上操作。 
READPAST: 跳过已经加锁的数据行,这个选项将使事务读取数据时跳过那些已经被其他事务锁定的数据行,而不是阻塞直到其他事务释放锁,READPAST仅仅应用于READ COMMITTED隔离性级别下事务操作中的SELECT语句操作。  
READUNCOMMITTED:等同于NOLOCK。   
REPEATABLEREAD:设置事务为可重复读隔离性级别。  
ROWLOCK:使用行级锁,而不使用粒度更粗的页级锁和表级锁。   
SERIALIZABLE:用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于 HOLDLOCK。  
1TABLOCK:指定使用表级锁,而不是使用行级或页面级的锁,SQL Server在该语句执行完后释放这个锁,而如果同时指定了HOLDLOCK,该锁一直保持到这个事务结束。  
TABLOCKX:指定在表上使用排它锁,这个锁可以阻止其他事务读或更新这个表的数据,直到这个语句或整个事务结束。  
UPDLOCK :指定在读表中数据时设置更新 锁(update lock)而不是设置共享锁,该锁一直保持到这个语句或整个事务结束,使用UPDLOCK的作用是允许用户先读取数据(而且不阻塞其他用户读数据),并且保证在后来再更新数据时,这一段时间内这些数据没有被其他用户修改。

参考文档:
博客园
博客园
CSDN

相关文章

  • 数据库为什么需要锁机制?有哪些锁机制?

    数据库为什么需要锁机制?有哪些锁机制?

  • 关于数据库锁机制

    书读百遍,不如 敲一遍代码...先解释一下名词 共享锁(S):一般是Select 查询是自带共享锁;共享锁允许多个...

  • MySQL的锁机制

    关于一些数据库的锁,之前有写过:锁和并发控制这篇着重讲讲MySQL的锁机制,由之前的理论转实际 1.MySQL的锁...

  • MySQL的锁

    数据库锁 概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。比...

  • 秒杀系统技术方案演变过程

    前言:秒杀系统需要保证商品库存不能出现超卖现象。一、数据库锁机制(悲观锁、乐观锁)实现秒杀(1)悲观锁:数据库本身...

  • MySQL锁机制

    锁机制是数据库与文件系统最大的差别了,而不同的数据库,不同的引擎锁机制也有所不同,由于MySQL的MyISAM用的...

  • 26、 请说说 MySQL 数据库的锁?

    请说说 MySQL 数据库的锁? 关于 MySQL 的锁机制,可能会问很多问题,不过这也得看面试官在这方面的知识储...

  • 多线程之锁

    其实常用也就那么几个锁,总感觉线程所用的锁机制和数据库的很相似,什么读写锁,就和数据库的共享锁,排他锁没什么区别....

  • 解决并发问题,数据库常用的两把锁!

    在写入数据库的时候需要有锁,比如同时写入数据库的时候会出现丢数据,那么就需要锁机制。 数据锁分为乐观锁和悲观锁 它...

  • Java面试必备之数据库乐观锁和悲观锁分析!

    在写入数据库的时候需要有锁,比如同时写入数据库的时候会出现丢数据,那么就需要锁机制。 数据锁分为乐观锁和悲观锁 它...

网友评论

    本文标题:关于数据库锁机制

    本文链接:https://www.haomeiwen.com/subject/qhyzwqtx.html