我有一个长时间运行的事务(称为 T1),它对 SQL Server 2008 R2 中的表执行一些删除、更新和插入操作。同时,另一个进程会定期从该表中运行 select 语句。
在默认隔离设置下(我认为是 READ COMMITTED?),T1 会阻止任何 select 语句运行,直到事务提交或回滚。
我希望看到的是,即使在事务正在进行时,select 语句也能对一致的数据起作用。我相信 SNAPSHOT 隔离可以提供帮助,但不确定我是否朝着正确的方向前进。这是该应用程序的最佳隔离级别吗?
其次,我无法控制调用 select 语句的进程,但我可以控制调用 T1 的 .NET 应用程序。select 语句和 T1 都需要更改任何隔离级别,还是仅将 T1 标记为具有不同的隔离级别就足够了?
MSDN 在线文章“ SQL Server 中的快照隔离”指出:
这不是自相矛盾的段落(“直到”与“保留”)吗?
那么,如果在关闭连接并将其返回到池后“保留了来自最后一个 SET TRANSACTION ISOLATION LEVEL 语句的隔离级别”,应该如何理解:
sql-server transaction isolation-level connection-pooling snapshot-isolation
我工作的公司目前使用 SQL Server 数据库(通常是最新的企业版)用于我们开发的产品。
我会将它描述为一个 OLTP 数据库,它具有大量时间关键应用程序的读写密集程度。除此之外,根据同一 OLTP 数据库(单独问题)中的信息显示了大量报告和图形数据,这些数据以频繁的速率读取和写入许多相同的表。
我们通常会遇到发生阻塞的问题,并且通常最终会减慢时间关键应用程序的速度,甚至由于这些应用程序中的死锁而导致问题。这个问题的常见解决方案似乎通常是对nolock有问题的查询提出提示。老实说,我讨厌这个解决方案,很长一段时间以来,我一直认为这是尝试解决这个问题的错误方法,从我阅读的所有内容中,我得出了相同的结论。
一段时间以来,我一直试图说服我的团队 RCSI 是我们绝对可以从中受益的东西,特别是考虑到我们的数据库类型。他们似乎认为这是一个很大的风险,并且经常因为风险因素而推迟它,但我们继续遇到性能问题,我们只是nolock在暗示它。
我正在寻找一种向我们的团队展示具体指标的好方法,以最终说服他们我们应该转向这种方法。
在存储过程中,我有以下内容:( sql server 2008 )
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION getStuff
BEGIN TRY
/* some selects, updates, etc, etc. */
....
COMMIT TRANSACTION getStuff
END TRY
BEGIN CATCH
...
END CATCH
Run Code Online (Sandbox Code Playgroud)
由于这是基于事务的,我认为其余的数据库连接不会受到 SERIALIZABLE 的影响。
我是否需要隐式设置隔离级别以在提交后读取已提交?这是否会对我的应用程序服务器和数据库服务器之间的其他连接产生不利影响?
我的系统中有很多死锁。
我想使用快照隔离来修复它们,但我的 DBA 对此有所保留。
他的担忧之一是快照隔离会减慢写入速度。这是因为它必须先写入缓存,然后写入 TempDb(行版本),然后才能返回给调用者。
“正常”写入可以只写入缓存然后完成。
这是行版本控制的工作方式吗?或者比这更复杂?它是否以某种方式并行执行这些操作?
还是快照隔离的写入速度较慢?
sql-server-2008 sql-server sql-server-2008-r2 snapshot isolation-level
在特定表上执行 select count(*) 时,我似乎遇到了很多死锁。我已经更改了所有必需的参数并将它们设置为仅行锁定。
我还更改了数据库以使用 READ_COMMITTED_SNAPSHOT 隔离,
但是,似乎使用 select count(*) where column = ? 在桌子上触发死锁或桌子上的锁..
我是否正确地认为 select count(*) 应该只访问中间行?但是,似乎并非如此,我仍然遇到死锁。适当的索引可能会有所帮助,
问题是:即使 read_committed_snapshot 设置为 on,SQL Server 2008 R2 是否在 select count(*) 期间在表上放置共享锁?
谢谢
我有一个存储过程,用于查询用于在我们的系统中分配工作的繁忙队列表。有问题的表在 WorkID 上有一个主键,没有重复项。
查询的简化版本是:
INSERT INTO #TempWorkIDs (WorkID)
SELECT
W.WorkID
FROM
dbo.WorkTable W
WHERE
(@bool_param = 0 AND
((W.InProgress = 0
AND ISNULL(W.UserID, -1) != @userid_param
AND (@bool_filtered = 0
OR W.TypeID IN (SELECT TypeID FROM #Types AS t)))
OR
(@bool_param = 1
AND W.InProgress = 1
AND W.UserID != @userid_param)
OR
(@Auto_Param = 0
AND W.UserID = @userid_param)))
OR
(@bool_param = 1 AND W.UserID = @userid_param)
OPTION
(RECOMPILE)
Run Code Online (Sandbox Code Playgroud)
该#Types表在过程中较早地填充。
正如我所说,WorkTable很忙,有时在此查询运行时,我怀疑其中一条记录正在从一组过滤器移动到另一组过滤器WHERE。具体来说,当有人开始处理一个项目,并且W.InProgress …
我有一个关于 SQL Server 的 UPDATE 语句的内部工作原理的问题。我试图了解如果同时收到或服务以下 2 个更新语句会发生什么:
| Session 1 - Statement 1 | Session 2 - Statement 2
| -------------------------+-------------------------
| update dbo.Table1 | update dbo.Table1
| set Value = 10 | set Value = 20
| where ID = 1 | where ID = 1
? and Value = 0; | and Value = 0;
(t)
Run Code Online (Sandbox Code Playgroud)
据我了解,更新将首先选择需要使用共享锁更新的行,这意味着两个更新语句都可以选择特定行。然后它请求一个排它锁来更新列值。因此,结果似乎将 Value 设置为 20。
我错过了什么还是我的理解正确?
连接的隔离级别设置为 READ UNCOMMITTED。
在我的应用程序中,我必须执行分布式锁定模式。因为我们已经有一个 SQL Server 实例可以使用,所以我们决定在我们的 Web 应用程序的 SQL 层实现锁定是最容易的。
可以根据多种条件获得锁,包括:
出于所有意图和目的,将上述两个条件视为int数据类型。
在这种模式中,我们希望将我们所有的锁都视为 FIFO,我相信SERIALIZABLE隔离级别会给我们带来这种好处。
以下是我们建议如何执行“锁定”:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
BEGIN
-- Awesome, the lock will be acquired
INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
END
ELSE
BEGIN
-- Someone already has the lock
SELECT -1
END
SET TRANSACTION ISOLATION LEVEL READ COMITTED
Run Code Online (Sandbox Code Playgroud)
和“解锁”:
DELETE FROM locks WHERE LockId = @LockId
Run Code Online (Sandbox Code Playgroud)
所以我的问题有两个方面: …
众所周知,Read Committed 隔离容易出现不同的异常。我阅读了伟大的保罗怀特关于隔离级别的系列。与讨论相关的帖子是这个:
它声明(再次,这是众所周知的),在读提交隔离下运行的语句:
Can encounter the same row multiple times;
Can miss some rows completely;
Run Code Online (Sandbox Code Playgroud)
我的问题是关于“缺失行”部分。讨论缺失行的示例通常使用以下查询来演示问题:
select count(*) from table.
我的问题是在“常规”选择查询中可以遗漏行吗?意思是,可以像这样的查询
select * from table
甚至
select * from table where id = @id
还会错过在该查询开始之前提交的行吗?此问题仅适用于使用锁定(而非 RCSI)提交的读取,因为 RCSI 不允许这些类型的异常。
isolation-level ×10
sql-server ×9
transaction ×3
concurrency ×2
locking ×2
deadlock ×1
duplication ×1
metrics ×1
snapshot ×1
t-sql ×1
update ×1