【问题标题】:Blocked on trip to MARS火星之旅受阻
【发布时间】:2022-11-07 19:46:00
【问题描述】:

我正在编写的数据库工具通过对sys.dm_exec_requests 运行并行查询来调查阻塞的查询,如果主查询被延迟以找到延迟的原因。

如果调查连接具有VIEW SERVER STATE 权限,则可以正常工作。但是,如果不是,sys.dm_exec_requests 只包含它运行的连接的条目——这对于一次只能运行一个查询的连接来说有点毫无意义。

进入 MARS,我第一次想到这个神秘的功能可能对某些东西有用。

启用 MARS 后,我可以在与我们正在调查的延迟查询相同的连接上运行调查查询。

但是,一个简单的测试表明,如果第一个 MARS 查询被阻止,显然第二个也是,即使第二个没有理由。

我在 LinqPad 中运行此测试代码(使用 Dappper 以获得更紧凑的代码示例,但我在不使用 Dapper 的应用程序中得到了相同的效果):

var csb = new SqlConnectionStringBuilder();
csb.TrustServerCertificate = true;
csb.DataSource = @".\";
csb.InitialCatalog = "...";
csb.IntegratedSecurity = true;

using var c0 = new SqlConnection(csb.ConnectionString);

csb.MultipleActiveResultSets = true;

using var c1 = new SqlConnection(csb.ConnectionString);
using var c2 = new SqlConnection(csb.ConnectionString);

// Begin the blocking transaction on connection #0
await c0.QueryAsync(@"
begin transaction
select * from mytable with (tablockx, holdlock)
");

// This query on connection #1 is blocked by connection #0
var blockedTask = c1.QuerySingleAsync<int>("select count(*) from mytable");

// Strangely, this second query is blocked as well
var requests = await c1.QueryAsync(@"
select session_id, cpu_time, reads, logical_reads
from sys.dm_exec_requests r
");

// We don't get here unless you swap `c1` for `c2` in the last query, making
// it run on it's own connection, thus requiring VIEW SERVER STATE to be useful
requests.Dump();

await blockedTask;

您只需要一个带有任何随机表的数据库来应用它。

【问题讨论】:

    标签: sql-server ado.net


    【解决方案1】:

    MARS 允许在同一连接上交错执行多个请求,而不是并发执行。

    对于阻塞的SELECT 查询,在选择查询完成或通过返回结果产生之前,无法执行同一连接上的其他查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2021-06-28
      • 2014-11-11
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      相关资源
      最近更新 更多