sql-server – 为什么SQL Server 2008在长时间的事务INSERT上阻塞SELECT?

前端之家收集整理的这篇文章主要介绍了sql-server – 为什么SQL Server 2008在长时间的事务INSERT上阻塞SELECT?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们正试图拥有一个只需要定期插入新记录的事务表.

这个简单的表需要我们随着时间的推移不断添加新的记录.此表中的事务量预计相当高,并且也可能需要几秒钟才能完成定期的事务批量导入(> 1000).

从这些数据中,我们然后执行一组select语句,将不同的列分组以返回所需的值.

从我们的初始测试中,我们发现与sql Server相关的瓶颈,阻止我们的SELECT在INSERTS事务中间.

下面是一个简单的例子,可以运行来说明问题.

– 简单DB表

create table LOCK_TEST (
LOCK_TEST_ID int identity,AMOUNT int);

– 在1个查询窗口中运行

begin tran
insert into LOCK_TEST (AMOUNT) values (1);
WAITFOR DELAY '00:00:15' ---- 15 Second Delay
insert into LOCK_TEST (AMOUNT) values (1);
commit

– 在查询2中并行运行

select SUM(AMOUNT)
from LOCK_TEST;

我希望Query 2直接返回,0到查询1完成,然后显示2.我们从不想看到从第二个查询返回1.

我们已经看过的答案与SELECT(NOLOCK)在select语句中相关.但是这违反了交易界限,返回的信息可能是财务性质的,我们不希望在我们的查询中看到任何不合规的细节.

我的问题似乎在INSERT方面…
为什么INSERT阻止SELECT语句即使不修改任何现有数据?

奖金积分问题:这是sql Server的“功能”,还是我们会在其他数据库中找到这个?

UPDATE
我现在有时间找到一个本地的oracle数据库,并运行相同的简单测试.这个测试通过我的预期.

那么我可以像我想要的那样经常运行查询,它将返回null直到第一个事务提交,然后返回2.

有没有办法让sql Server这样工作?还是我们需要迁移到Oracle?

解决方法

此锁定行为是sql Server的一项功能.
使用2005年及以上版本,您可以使用 row level versioning(这是Oracle上默认使用的)来实现相同的结果&不阻止你的选择.这会给tempdb带来额外的压力,因为tempdb维护了行级版本控制,因此请确保适应这种情况.
要使sql以您想要的方式运行,请运行以下命令:
ALTER DATABASE MyDatabase
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON

猜你在找的MsSQL相关文章