发布网友 发布时间:2022-04-25 21:02
共6个回答
懂视网 时间:2022-04-13 04:54
最近在处理一个锁的问题时,发现一个比较郁闷的事,使用X锁居然无法锁住查询,模拟这个问题,可以使用如下T-SQL脚本来建立测试环境。
USE master; GO IF @@TRANCOUNT > 0 ROLLBACK TRAN; GO -- ======================================= -- 建立测试数据库 -- a. 删除测试库, 如果已经存在的话 IF DB_ID(N'db_xlock_test') IS NOT NULL BEGIN; ALTER DATABASE db_xlock_test SET SINGLE_USER WITH ROLLBACK AFTER 0; DROP DATABASE db_xlock_test; END; -- b. 建立测试数据库 CREATE DATABASE db_xlock_test; -- c. 关闭READ_COMMITTED_SNAPSHOT 以保持SELECT 的默认加锁模式 ALTER DATABASE db_xlock_test SET READ_COMMITTED_SNAPSHOT OFF; GO -- ======================================= -- 建立测试表 USE db_xlock_test; GO CREATE TABLE dbo.tb( id int IDENTITY PRIMARY KEY, name sysname ); INSERT dbo.tb SELECT TOP(50000) O1.name + N'.' + O2.name + N'.' + O3.name FROM sys.objects O1 WITH(NOLOCK), sys.objects O2 WITH(NOLOCK), sys.objects O3 WITH(NOLOCK); GO
然后,建立一个连接,执行下面的脚本来实现加锁。
-- ======================================= -- 测试连接1 - 加锁 BEGIN TRAN --测试的初衷是通过SELECT加锁,结果发现UPDATE也锁不住 UPDATE dbo.tb SET name = name --SELECT COUNT(*) FROM dbo.tb WITH(XLOCK) WHERE id <= 2; SELECT spid = @@SPID, tran_count = @@TRANCOUNT, database_name = DB_NAME(), object_id = OBJECT_ID(N'dbo.tb', N'Table'); -- 显示锁 EXEC sp_lock@@SPID;
通过执行结果,可以看到对象被加锁的情况:表级和页级上是IX锁,记录上是X锁。
spid | tran_count | database_name | object_id | |||||||
51 | 1 | db_xlock_test | 21575115 | |||||||
spid | dbid | ObjId | IndId | Type | Resource | Mode | Status | |||
51 | 7 | 0 | 0 | DB | S | GRANT | ||||
51 | 7 | 21575115 | 1 | PAG | 0.0951388 | IX | GRANT | |||
51 | 7 | 21575115 | 0 | TAB | IX | GRANT | ||||
51 | 1 | 1131151075 | 0 | TAB | IS | GRANT | ||||
51 | 7 | 21575115 | 1 | KEY | (020068e8b274) | X | GRANT | |||
51 | 7 | 21575115 | 1 | KEY | -100870766 | X | GRANT | |||
然后新建一个连接,执行下面的T-SQL查询,看看会否被连接1锁住
-- ======================================= -- 测试连接2 - 被阻塞(在测试连接1 执行后执行) SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT * FROM dbo.tb WHERE id <= 2;
上述查询会很快返回结果,并不会被查询1阻塞住。
按照我们的了解(联机帮助上也有说明),在READ COMMITTED事务隔离级别下,查询使用共享锁(S),而根据锁的兼容级别,S锁是与X锁冲突的,所以正常情况下,连接2的查询需要等待连接1执行完成。可是测试的结果去违反了这一原则。
为了了解为什么连接2不会被阻塞,对连接2做了一个Trace,发现一个更郁闷的问题,Trace的结果如下:
EventClass | TextData | ObjectID | Type | Mode |
Lock:Acquired | 21575115 | 5 - OBJECT | 6 - IS | |
Lock:Acquired | 1:77 | 0 | 6 - PAGE | 6 - IS |
Lock:Acquired | [PLANGUIDE] | 0 | 2 - DATABASE | 3 - S |
Lock:Acquired | 21575115 | 5 - OBJECT | 6 - IS | |
Lock:Acquired | 1:77 | 0 | 6 - PAGE | 6 - IS |
Lock:Acquired | 1:80 | 0 | 6 - PAGE | 6 - IS |
Lock:Acquired | 1: | 0 | 6 - PAGE | 6 - IS |
Trace的前面两行是连接2的Trace结果,从结果看,连接2仅使用了意向共享锁(IS),而且只是表级和页级,按照锁的兼容性原则,IS和IX(连接1在表级和页级仅使用了IX锁)是不冲突的,所以连接2的查询不会被阻塞。在增加了查询的数据量后,Trace结果表明查还是只在表级和页级使用了IS锁(Trace结果的最后4行)。
对于这个问题,解决的办法当然就是提升连接1锁的粒度,使用PAGLOCK表提示将锁的粒度提升到页级,这样IS与X是冲突的,就可以成功阻塞连接2。
但疑问就是,为什么查询只在表级和页级下意向共享锁(IS),而不在行级下共享锁(X),这个似乎与联机帮助上的说明不一样(还是一直以来理解上的偏差呢)。
附:联机帮助上关于锁模式的说明
var cpro_id = "u6292429";
热心网友 时间:2022-04-13 02:02
需要选择合适的防盗锁。
1、选择防拔防撬面板。劣质面板带来不小的安全隐患,小偷用特制的大力钳,最快30秒内就可以将防盗门上的插芯锁面板拔掉,再掰断锁芯。
2、购买防盗锁锁芯。
购买时看钥匙的“牙齿”。牙越多,齿越深,排列越复杂,开启难度越大,防盗性能越好。
3、挑锁论斤称两,一比重量二看锁芯。重量越重,锁芯质量越好,锁芯内的珠子越多,防盗功能越好。
4、选锁芯看颜色,比色泽,看做工。质量好的锁芯采用电镀处理,表面光滑,色泽明亮。其中颜色深黄的是铜芯,比较坚固,防盗性能较好;锁芯色泽暗淡,颜色灰白有气泡的是锌合金,防盗性能一般。
5、钥匙旋转插入锁芯被卡的防盗性能差,钥匙半插入后,用5至7分力顺时针或者逆时针旋转并继续将钥匙压进锁口,被卡的钥匙说明锁芯防盗性能差,顺利在半旋转状态插进锁芯的说明防盗效果好。
热心网友 时间:2022-04-13 03:20
要看门锁是否出现问题或者是门禁系统的门禁电源这些等情况@#@#@#熙南科技门锁看门的吸力不够看门禁锁的锁体和吸板是否固定在一个水平面上等等。。。
热心网友 时间:2022-04-13 04:55
它需要修理了。
热心网友 时间:2022-04-13 06:46
该换锁芯了
热心网友 时间:2022-04-13 08:54
检查一下是不是锁出了问题,或者门有松动或者偏斜