当前位置: 首页 > 面试题库 >

使用PreparedStatements时SQL Server死锁

太叔景曜
2023-03-14
问题内容

我有一个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();

我发现运行JMeter脚本模拟2个用户时,此语句在数据库中导致死锁。

我想检查一下SQL事件探查器中的值,因此我使用了以下代码,因此可以检查这些值。

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

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

是否有人可以告诉我正在发生的事情和/或如何解决?


问题答案:

好的,我终于找到了问题,并找到了解决方案。

看来jTDS JDBC驱动程序与MSSQL的结合是“问题”。

本文准确地解释了我的情况。借助此常见问题解答,我能够将数据源设置为正确的配置。

据我了解:

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

我希望这也会对其他人有所帮助。



 类似资料:
  • 读者: 这看起来像是一个僵局,但有几件事让我怀疑: 我找不到另一个可能持有相同锁的线程 4秒后进行线程转储会得到相同的结果,但现在所有线程都报告,这与第一次转储中的不同。

  • 问题内容: 我已升级到最新的Java 7 build 1.7.0_60-b19,但问题仍然存在。 我进行了另一个线程转储,发现了相同的问题:在DefaultCorrelatingMessageHandler锁调用中,所有DefaultMessageListenerContainers(计数为20)都由taskScheduler(entityScheduler-3)锁定。 这是调度程序和聚合器配置:

  • 我有一个关于管理线程的简单问题。我有3个进程,它们与一个许可证共享相同的信号量。在正常情况下,第一道工序采用该许可证,第二道工序发放两个许可证。第二个过程版本3允许进行第三个过程。我举了一个例子来说明我的问题。 第一个: 第二道工序: } 最后一个: 问题是。当我运行这三个进程并确保进程3是第一个执行的进程时。我会死锁。进程2永远不会打印“Hello 3”,进程1永远不会打印“Hello 2”。为

  • 本文向大家介绍查询Sqlserver数据库死锁的一个存储过程分享,包括了查询Sqlserver数据库死锁的一个存储过程分享的使用技巧和注意事项,需要的朋友参考一下 使用sqlserver作为数据库的应用系统,都避免不了有时候会产生死锁, 死锁出现以后,维护人员或者开发人员大多只会通过sp_who来查找死锁的进程,然后用sp_kill杀掉。利用sp_who_lock这个存储过程,可以很方便的知道哪个

  • 众所周知,有两种锁定策略:乐观锁定和悲观锁定 悲观锁定是锁定记录供您独占使用,直到您使用完它。它比乐观锁定具有更好的完整性,但是需要您小心应用程序设计以避免死锁。 也知道,乐观并发控制与多版本并发控制(Oracle或MSSQL-Snapshot/MVCC-RC)不同:乐观与多版本并发控制-差异? 但是,如果在两个事务中都使用OCC(乐观并发控制),会在两个交易之间发生死锁吗? 我们可以说乐观锁通过

  • node-sqlserver 是微软官方发布的 SQL Server 的 Node.js 的驱动程序。可允许 Windows 上运行的 Node.js 程序访问 SQL Server 和 Windows Azure SQL 数据库。 该项目托管在 Github 上。