使用 PreparedStatements 时 SQL Server 死锁

Han*_*sen 4 java sql-server concurrency prepared-statement database-deadlocks

我有一个 java servlet 应用程序,我正在使用准备好的查询来更新 SQL Server 数据库表中的记录。

假设我想执行UPDATE MyTable SET name = 'test' WHERE id = '10'. (是的,id 是一个 varchar)
我使用以下代码来实现这一点:

PreparedStatement pstmt = con.prepareStatement("UPDATE MyTable SET name = ? WHERE id = ?");
pstmt.setString(1, getName() );
pstmt.setString(2, getID() );
pstmt.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

我发现当我运行一个 JMeter 脚本来模拟 2 个用户时,这个语句会导致我的数据库出现死锁。

我想检查我在 SQL Profiler 中的值,所以我使用了以下代码,以便我可以检查这些值。

String query = String.format("UPDATE MyTable SET name = '%s' WHERE id = '%s' ", getName(), getID() );
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.executeUpdate();
Run Code Online (Sandbox Code Playgroud)

突然间,我的僵局消失了!遗憾的是,最后一种方法容易受到 SQL 注入的影响。

有没有人可以告诉我发生了什么和/或如何解决它?

Han*_*sen 5

好的,我终于找到了问题和解决我的问题的方法。

jTDS JDBC 驱动程序与 MSSQL 的组合似乎是“问题”。

这篇文章准确地解释了我的情况。在这个 FAQ的帮助下,我能够将数据源设置为正确的配置。

据我了解:

如果您有使用类似字符串的索引的语句(就像在我的情况下一样),该表将执行索引 SCAN 而不是索引 SEEK。这会导致整个表被锁定并容易出现死锁。

我希望这也能帮助其他人。