SQLSERVER 怎样使查询不占锁

对一些相对不怎么敏感的数据,不需要太及时性的数据,不需要占锁。

要在SQL Server中执行查询而不占用锁,可以采取以下几个策略:

1、使用NOLOCK提示: 最直接但风险较高的方法是在查询中使用WITH (NOLOCK)提示。这样,SQL Server会在读取数据时不获取共享锁,从而避免阻塞其他事务的写操作。但是,这可能导致读取“脏读”(未提交的数据)或重复读取(因并发修改而被删除或更改的数据)。因此,这个选项通常仅推荐用于只读查询,尤其是报表或数据分析场景,并且能接受数据可能不完全准确的风险。

SELECT * FROM YourTable WITH (NOLOCK)

此策略不要认为数据库库不会产生任何锁。实质上,使用了WITH(NOLOCK)后,数据库依然对该表对象生成Sch-S(架构稳定性)锁以及DB类型的共享锁,不要认为不会被其它会话阻塞,依然可能会产生Schema Change Blocking

2、 快照隔离级别: 更安全的做法是将数据库或会话的事务隔离级别设置为快照隔离(SNAPSHOT)。在快照隔离下,查询不会阻塞其他事务,也不会被其他事务阻塞,因为每个事务看到的是数据的一个快照版本,而不是实际的行锁。不过,这会增加版本存储的需求。设置会话级别的快照隔离:

SET TRANSACTION ISOLATION LEVEL SNAPSHOT;

3、 使用READ_COMMITTED_SNAPSHOT: 启用数据库的READ_COMMITTED_SNAPSHOT选项,使得在读取已提交隔离级别下执行的查询也能像快照隔离一样不阻塞。这样可以在不改变应用程序代码的情况下减少锁争用。 

-- 启用数据库的事务快照隔离级别
ALTER DATABASE YourDatabaseName 
SET ALLOW_SNAPSHOT_ISOLATION ON;

 

 
--设置数据库为SINGLE_USER模式,减少锁定时间
ALTER DATABASE YourDatabaseName SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE YourDatabaseName SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE YourDatabaseName SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE YourDatabaseName SET MULTI_USER
SELECT 
    name AS DatabaseName,
    is_read_committed_snapshot_on,
    CASE 
        WHEN snapshot_isolation_state = 0 THEN 'OFF'
        WHEN snapshot_isolation_state = 1 THEN 'ON'
        WHEN snapshot_isolation_state = 2 THEN 'IN_TRANSITION_TO_ON'
        WHEN snapshot_isolation_state = 3 THEN 'IN_TRANSITION_TO_OFF'
        ELSE 'UNKNOWN'
    END AS SnapshotIsolationStateDesc
FROM 
    sys.databases
WHERE 
    name = DB_NAME(); -- 查询当前数据库,如果需要检查所有数据库,可以删除此条件或替换为具体的数据库名

设置方法  参考文章 如何修改数据库的快照隔离级别_read committed snapshotison为1-CSDN博客

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值