小编Goo*_*SQL的帖子

只插入死锁

我们有一个将数据插入表中的应用程序。不幸的是,我们遇到了死锁,而且死锁仅来自插入。我们看到插入在非聚集索引上以不同的顺序获取键锁,这导致了问题。

为什么插入会这样,我们应该怎么做才能缓解死锁?任何帮助或见解表示赞赏。

在下面的示例中,只涉及两个插入,但我们在死锁中涉及多达 4 个不同的插入。

这是死锁图:

    <deadlock>
    <victim-list>
        <victimProcess id="process3ab355868" />
    </victim-list>
    <process-list>
        <process id="process3ab355868" taskpriority="0" logused="1184" waitresource="KEY: 5:72057594043629568 (6234ed5bf036)" waittime="7493" ownerId="92332106" transactionname="implicit_transaction" lasttranstarted="2014-10-13T12:37:43.060" XDES="0x123699668" lockMode="X" schedulerid="3" kpid="3540" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2014-10-13T12:37:44.333" lastbatchcompleted="2014-10-13T12:37:44.333" lastattention="1900-01-01T00:00:00.333" clientapp="Microsoft JDBC Driver for SQL Server" hostname="" hostpid="0" loginname="" isolationlevel="read committed (2)" xactid="92332106" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
            <executionStack>
                <frame procname="adhoc" line="1" stmtstart="278" stmtend="818" sqlhandle="0x0200000053a65d302154b91e9fee55234669030a42479c050000000000000000000000000000000000000000">
                    INSERT INTO table (col1, col2, col3, col4, col5, col6, col7, col8, col9) VALUES (@P0, @P1, @P2, @P3, @P4, @P5, …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock insert sql-server-2012

7
推荐指数
1
解决办法
1457
查看次数

阻止对主 AG 副本进行读取访问,但允许在可读辅助副本上进行读取访问

我们有一个独特的情况,我们希望允许用户使用 SSMS 查询数据库的可读辅助副本以进行临时报告,但不允许他们从主副本中读取数据。我们设置了只读路由来完成此任务。这也是 SQL 2016 上的全部。

我最初的想法是在主副本和辅助副本上创建登录名,并授予对相关数据库的读取访问权限。然后我们将拒绝连接或禁用当前主副本上的登录。在 SSMS 中,用户可以使用 ApplicationIntent=ReadOnly 连接到侦听器,并路由到辅助副本,而无需接触主副本。

我们将使用基本逻辑在主副本服务器和辅助副本服务器上设置一个简单的作业:如果当前服务器=主服务器,则禁用登录;如果当前服务器 = 辅助服务器,则启用登录。

问题是,当在主服务器上禁用登录时,以只读意图连接到侦听器时,我会遇到登录失败。当我在主副本上重新启用登录时,它工作得很好,并且连接已正确路由到可读的辅助副本。

我在主服务器上设置了跟踪,果然,我可以看到登录连接并在主副本上的 master 和 msdb 中运行一些系统类型查询 - 即使我在 SSMS 中使用 ApplicationIntent=ReadOnly 进行连接。我不确定这是否是 SSMS 在幕后执行的操作,或者是否是登录通过只读路由过程的默认行为。

以下是我在主数据库上使用快速分析器跟踪捕获的查询:

--msdb query

    select 
        case 
            when object_id('dbo.sysdac_instances') is not null then 1             
        else
            0 
        end

--master query

SELECT
dtb.name AS [Name],
dtb.database_id AS [ID],
CAST(has_dbaccess(dtb.name) AS bit) AS [IsAccessible]
FROM
master.sys.databases AS dtb
ORDER BY
[Name] ASC
Run Code Online (Sandbox Code Playgroud)

以前有人处理过这种情况吗?看来我们基本上需要允许主副本上的登录连接权限,同时拒绝其对主副本上 AG 中的数据库的读取访问权限,但授予该登录权限以读取可读辅助副本上的数据库。

另一种选择是创建一个直接指向辅助副本的 DNS 条目,但我们不能保证该副本始终是辅助副本,因为可能会发生故障转移。

sql-server availability-groups read-only-database sql-server-2016

2
推荐指数
1
解决办法
3133
查看次数