为了账号安全,请及时绑定邮箱和手机立即绑定

在一个事务中插入和更新时 Sql server 死锁

在一个事务中插入和更新时 Sql server 死锁

动漫人物 2022-06-23 16:55:19
我正在使用 Azure SQL + Java + Spring Boot 2。目前我正在尝试了解死锁发生的原因。在事务中,我正在对同一张表但不同的行进行插入和更新。据我了解,SQL Server 默认使用rowlock和read_committed隔离。这是死锁的详细信息:<deadlock>    <victim-list>        <victimProcess id="process2b8618644e8"/>    </victim-list>    <process-list>        <process id="process2b8618644e8" taskpriority="0" logused="352"                 waitresource="KEY: 16:72057594043760640 (5f601e0257f1)" waittime="1321" ownerId="9246067"                 transactionname="implicit_transaction" lasttranstarted="2019-02-17T13:03:49.683" XDES="0x2b868778458"                 lockMode="U" schedulerid="2" kpid="288932" status="suspended" spid="118" sbid="0" ecid="0" priority="0"                 trancount="2" lastbatchstarted="2019-02-17T13:03:49.793" lastbatchcompleted="2019-02-17T13:03:49.760"                 lastattention="1900-01-01T00:00:00.760" clientapp="Microsoft JDBC Driver for SQL Server"                 hostname="TZ-MacBook-Pro.local" hostpid="0" loginname="master" isolationlevel="read committed (2)"                 xactid="9246067" currentdb="16" currentdbname="test" lockTimeout="4294967295" clientoption1="671088672"                 clientoption2="128058">            <executionStack>                <frame procname="unknown" queryhash="0x431f2517c2d3feb8" queryplanhash="0x3a793ad664472011" line="1"                       stmtstart="110" stmtend="238"                       sqlhandle="0x02000000060c530e608cef3b3e4e4712f48c40d2efd9b04d0000000000000000000000000000000000000000">                    unknown                </frame>                <frame procname="unknown" queryhash="0x0000000000000000" queryplanhash="0x0000000000000000" line="1"                       sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">                    unknown                </frame>            </executionStack>此外,我在 id 列上使用了聚集索引,随机操作顺序没有问题。此外,当我只在事务中插入时,一切正常,没有死锁。 如果我切换到 PostgreSql,则不会出现死锁问题。那么,为什么我在 Azure SQL 中遇到了死锁?
查看完整描述

1 回答

?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

死锁的一个常见原因是需要查询和索引调整的查询触及的数据多于必要的数据。

死锁跟踪显示参数作为nvarchar(4000)数据类型传递。这可能会阻止有效使用列上的索引,varchar因为nvarchar它的数据类型优先级高于varchar. 当从应用程序数据类型推断参数数据类型时,此问题尤其常见,因为字符串通常是 Unicode,例如在 Java 和 .NET 语言中,导致nvarchar参数与基础列数据类型无关。

解决方案是对字符串使用 varchar 参数而不是 nvarchar,除非基础列是nvarchar. 如果您不在nvarchar数据库中使用,请指定 JDBC 连接字符串参数sendStringParametersAsUnicode,如本答案中所述。或者,更改应用程序代码或框架配置以使用列的varchar参数类型varchar

最佳实践是确保参数与基础数据库列的类型相匹配。这将提高性能和并发性,并且还有其他好处。


查看完整回答
反对 回复 2022-06-23
  • 1 回答
  • 0 关注
  • 193 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信