可重复读取 - 我理解对吗?

发布于 2024-08-17 20:15:51 字数 243 浏览 5 评论 0原文

尝试完全理解 SQL Server 隔离级别 - 特别是可重复读取。

我有一个存储过程,它启动一个事务并将光标放在一些数据上(嘘声)。这可能是相当大的数据块,因此可能需要一段时间才能完成。

然后它将提交或回滚。

在此期间,在事务关闭之前,如果有人调用导致某些受影响的行被读取的方法,我的理解是该方法将停止,直到第一个方法完成。然后他们将获得数据(只要首先没有发生超时)

我认为我是对的,但问题是 - 我是吗?

Trying to completely understand SQL Server Isolation Levels - notably REPEATABLE READ.

I have a sproc that starts a transaction and puts a cursor around some data (boo hiss). This can be a fair chunk of data, so can take a while to do.

It will then COMMIT or ROLLBACK.

During this time, before the transaction has been closed, if someone calls a method which causes some of those affected rows to be READ, my understanding is that this method will stall until the first method is complete. They will then be served up the data (as long as a time-out doesn't occur first)

I think I'm right, but question is - am I?!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

っ〆星空下的拥抱 2024-08-24 20:15:51

REPEATABLE READ 会阻止 SELECT 解除它们放置的共享锁,直至事务结束。

将事务 1 设置为 READ COMMITTED,在事务 2 中选择行后,您可以更新事务 2 中的行<代码>1。

如果事务 1REPEATABLE READ,则在事务 2 中选择行后,您无法更新事务 2 中的行<代码>1。

场景:

READ COMMITTED

1 SELECT -- places a shared lock and immediately lifts it.
2 UPDATE -- places an exclusive lock. Succeeds.
1 SELECT -- tries to place a shared lock but it conflicts with the exclusive lock placed by 2. Locks.

REPEATABLE READ

1 SELECT -- places a shared lock and keeps it
2 UPDATE -- tries to places an exclusive lock but it's not compatible with the shared lock. Locks
1 SELECT -- the lock is already placed. Succeeds.

更新:

至于你的问题:在SQL Server中,SELECTs即使使用也不会互相锁定可重复读取,因为它们放置的共享锁彼此兼容:

CREATE TABLE t_lock (id INT NOT NULL PRIMARY KEY, value INT NOT NULL)
INSERT
INTO    t_lock
VALUES (1, 1)

-- Session 1

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 2

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 1

DEALLOCATE cr_lock
COMMIT

-- Session 2

DEALLOCATE cr_lock
COMMIT

REPEATABLE READ prevents SELECTs from lifting shared locks they placed until the end of the transaction.

With transaction 1 as READ COMMITTED, you can update a row in transaction 2 after you selected it in transaction 1.

With transaction 1 as REPEATABLE READ, you cannot update a row in transaction 2 after you selected it in transaction 1.

The scenarios:

READ COMMITTED

1 SELECT -- places a shared lock and immediately lifts it.
2 UPDATE -- places an exclusive lock. Succeeds.
1 SELECT -- tries to place a shared lock but it conflicts with the exclusive lock placed by 2. Locks.

REPEATABLE READ

1 SELECT -- places a shared lock and keeps it
2 UPDATE -- tries to places an exclusive lock but it's not compatible with the shared lock. Locks
1 SELECT -- the lock is already placed. Succeeds.

Update:

As for you question: in SQL Server, SELECTs will not lock each other even with REPEATABLE READ, since shared locks they place are compatible with each other:

CREATE TABLE t_lock (id INT NOT NULL PRIMARY KEY, value INT NOT NULL)
INSERT
INTO    t_lock
VALUES (1, 1)

-- Session 1

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 2

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 1

DEALLOCATE cr_lock
COMMIT

-- Session 2

DEALLOCATE cr_lock
COMMIT
荒路情人 2024-08-24 20:15:51

正确的。

来自 MSDN 的完整说明:

指定语句无法读取
已修改但未修改的数据
尚未由其他事务提交
并且没有其他交易可以
修改已读取的数据
当前交易直到当前
交易完成。

共享锁被放置在所有数据上
中的每个语句读取
交易并保留至
交易完成。这可以防止
修改任何其他交易
已读取的行
当前交易。其他
事务可以插入新行
符合搜索条件
当前发布的声明
交易。如果当前
然后事务重试该语句
它将检索新行,其中
导致幻读。因为
共享锁一直保持到a的末尾
交易而不是被释放
在每条语句的末尾,
并发数低于默认值
READ COMMITTED 隔离级别。使用
仅在必要时才使用此选项。

Correct.

A full description from MSDN:

Specifies that statements cannot read
data that has been modified but not
yet committed by other transactions
and that no other transactions can
modify data that has been read by the
current transaction until the current
transaction completes.

Shared locks are placed on all data
read by each statement in the
transaction and are held until the
transaction completes. This prevents
other transactions from modifying any
rows that have been read by the
current transaction. Other
transactions can insert new rows that
match the search conditions of
statements issued by the current
transaction. If the current
transaction then retries the statement
it will retrieve the new rows, which
results in phantom reads. Because
shared locks are held to the end of a
transaction instead of being released
at the end of each statement,
concurrency is lower than the default
READ COMMITTED isolation level. Use
this option only when necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文