SQL Server 根据主键更新数据却使用Cluster Index Scan问题

本文分析了一种在SQL Server中由于参数类型不匹配导致的死锁现象。通过使用SQL Server Profiler工具,揭示了更新语句在特定条件下如何错误地执行全表扫描而非索引查找,进而引发了死锁。解决方案涉及调整JDBC连接字符串设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目很多job在同一时刻同时启动,结果一直发生死锁问题, 通过Sqlserver profiler 分析发现 似乎是2张表的insert 和 update 发生互锁, 大致情景如下:




 












通过sql server profiler 发现这里的update 需要在主键索引上加U锁但是却在等待另一个transaction的insert 的之后x 锁,update 是根据主键来更新的 不应该出现这种情况啊 , 后来在分析update语句的执行计划



[code="sql"](@P0 nvarchar(4000),..@P11 nvarchar(4000))UPDATE TBL_SR_MAST SET SR_NO =  @P0 , .. WHERE SR_ID =  @P11







Clustered Index Update(OBJECT:(...)





  |--Compute Scalar(..[Expr1012]=CONVERT_IMPLICIT(varchar(32),[@P10],0)))





       |--Top(ROWCOUNT est 0)





            |--Clustered Index Scan(OBJECT:(.. WHERE:(CONVERT_IMPLICIT(nvarchar(32),..,0)=[@P11]) ORDERED)



这里明明是主键更新,居然出现Clustered Index Scan 而不是 Cluster Index Seek, 所以导致等待另一个transaction 的 insert 的索引锁,后来发现sql server 查询语句参数化的时候如果参数的类型和表中字段类型不一致的时候就会发生Clustered Index Scan,而正常的使用jdbc的preparedstament的时候 是默认以unicode的方式向database 发送string的, sqlserver 会解析成ncarchar的数据库类型,就导致了这个问题。 最后是在



jdbc url 上加上sendStringParametersAsUnicode=false 参数( jdbc:jtds:sqlserver://....;sendStringParametersAsUnicode=false),解决了死锁问题。 但是这样改制后有个问题就是如果表中确实有nvarchar的字段可能会导致一些 问题或者 乱码。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值