SQL - Why SELECT query has been BLOCKED by INSERT?

时间:2019-05-19 04:08:26

标签: sql sql-server transactions

I always thought the writers never block the readers (and vice versa).

However, what am seeing right now is very strange. I'm probably wrong and am missing something here. So please help as this is driving me crazy!

Today I created a very simple table:

USE [testdb]
GO

CREATE TABLE [dbo].[MyTab](
    [N] [int] NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[MyTab]  WITH CHECK ADD CHECK  (([n]>(10)))
GO

Then I populated it with a few rows.

Next I decided to set IMPLICIT_TRANSACTIONS to ON and select from the table in another session in a completely separate execution of the SQL Server Management Studio. The below snapshot demonstrates what hapened:

enter image description here

You see the issue? The select query is still executing! This query never returns. It returns only after I commit or rollback the insert statement. I tested the same scenario multiple times and the same thing happened over and over again.

To further confirm my observation, have a look at the below report:

enter image description here

Can you help and let me know what am I doing wrong?

or if my assumption that readers cannot be blocked is entirely (or partially) wrong?

Thanks!

Note: Initially I was connected as the same user as the insert session when I wanted to query the table. Once I saw my select was blocked, I decided to login and test using another user. Hence, the using as 'sa' account. :)

2 个答案:

答案 0 :(得分:2)

进行一些研究后,我才意识到问题出在哪里。实际上,在SQL Server中,读写器有时确实会互相阻塞。这与甲骨文的读者和作者从不互相阻碍的情况不同。

进一步的说明

我是Oracle DBA,对SQL Server数据库不太了解。今天的观察令我感到惊讶,因为在Oracle中我从未见过选择查询被插入语句阻塞,这是因为按照Oracle's documentation

  

读者和作家在Oracle数据库中不会互相阻碍。   因此,虽然查询仍然看到一致的数据,但两者都读取   提交和可序列化的隔离提供了高水平的   并发以实现高性能,而无需阅读   未提交的数据。

这与SQL Server read queries may be blocked under certain circumstances完全不同。

答案 1 :(得分:2)

如果您打开READ_COMMITTED_SNAPSHOT数据库选项,则读者不会阻止SQL Server中的作家(反之亦然)。然后,SQL Server将使用行版本控制而不是锁定来为READ_COMMITTED事务提供读取一致性,其行为类似于您更熟悉的Oracle DBMS。

READ_COMMITTED_SNAPSHOT默认情况下在Azure SQL数据库中处于启用状态,但在内部SQL Server版本中未启用,以实现向后兼容性。