我们正在尝试建立一个只定期插入新记录的事务表。
这个简单的表需要我们随着时间的推移不断向其中添加新记录。该表中的事务量预计会相当高,并且可能会定期批量导入事务(>1000),这可能需要几秒钟才能完成。
然后,我们根据这些数据执行一组选择语句,对不同的列进行分组以返回所需的值。
从我们最初的测试中,我们发现了一个与 SQL Server 相关的瓶颈,该瓶颈在插入事务中间时会阻止我们的 SELECT。
下面是一个可以运行来说明问题的简单示例。
-- 简单数据库表
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;
我希望查询 2 立即返回 0,直到查询 1 完成,然后显示 2。我们永远不想看到第二个查询返回 1。
我们已经看到的答案与 select 语句上的WITH (NOLOCK) 相关。但这违反了事务边界,并且返回的信息本质上可能是财务信息,我们不希望在查询中看到任何未提交的详细信息。
我的问题似乎出在 INSERT 方面......
为什么 INSERT 会阻止 SELECT 语句,即使它没有修改任何现有数据?
积分问题:这是 SQL Server 的“功能”吗?或者我们也会在其他数据库风格中找到此功能吗?
UPDATE我现在有时间找到本地 Oracle 数据库并运行相同的简单测试。这次测试通过了,正如我所期望的那样。
即,我可以根据需要多次运行查询,并且它将返回 null,直到第一个事务提交,然后返回 2。
有没有办法让 SQL Server 像这样工作?或者我们需要迁移到 Oracle?