Java 应用程序在调用PreparedStatement(针对 SQL Server DB)后挂起

标签 java sql-server-2008-r2 locking prepared-statement jtds

我正在尝试掌握一个与 SQL Server 2008 R2 DB 通信的 Java 应用程序。该应用程序将数据导入数据库,并且它具有“测试模式”;数据库请求被包装在一个事务中,该事务在最后回滚。

对于特定数据集,该工具会禁用触发器,然后在导入后重新启用它。在测试模式下,在第一次通过时,一切都按预期工作 - “导入”的数据集没有问题。但是,如果我尝试重复该练习,应用程序会在尝试禁用触发器时挂起。

查看 SQL Profiler,我可以看到 RPC:Completed 跟踪项,这表明 SQL Server 已收到并成功处理了请求。此时,我希望 Java 应用程序能够获得控制权并继续 - 但事实并非如此,我正在努力思考下一步该往哪里看。

Java 代码:

String sql = "ALTER TABLE MyTable DISABLE TRIGGER ALL";
PreparedStatement stmt = mDBConnection.prepareStatement (sql);
stmt.execute();

跟踪文本数据:

declare @p1 int
set @p1=1
exec sp_prepare @p1 output,N'',N'ALTER TABLE MyTable DISABLE TRIGGER ALL',1
select @p1

:知道问题出在哪里吗?或者对我如何进一步调查有什么建议?

更新: 当然,上面的跟踪仅显示了 sp_prepare。有一个相应的 sp_execute 语句 - 并且缺少 RPC:Completed 跟踪项,表明问题出在 SQL Server 端。修改后的跟踪显示 RPC:Starting 条目 ('exec sp_execute 1'),但没有匹配的 RPC:Completed。

我可以在 SSMS 中运行 sp_prepare 和 sp_execute(假设我删除了 set 语句),正如预期的那样 - 毕竟它在第一次传递时执行正常。

解决方案: 使用 sp_who2 (见下文),我可以看到第一个连接/spid 第二个被阻止;在提交时,数据库连接已关闭,但在回滚时却没有关闭。由于我在测试和回滚模式下运行,因此这是问题的症结所在 - 关闭连接解决了问题。

sp_who2:

CREATE TABLE #sp_who2 
(
   SPID INT,  
   Status VARCHAR(1000) NULL,  
   Login SYSNAME NULL,  
   HostName SYSNAME NULL,  
   BlkBy SYSNAME NULL,  
   DBName SYSNAME NULL,  
   Command VARCHAR(1000) NULL,  
   CPUTime INT NULL,  
   DiskIO INT NULL,  
   LastBatch VARCHAR(1000) NULL,  
   ProgramName VARCHAR(1000) NULL,  
   SPID2 INT,
   RequestID int
) 
GO

INSERT INTO #sp_who2 EXEC sp_who2
GO

SELECT spid, status, blkby, command, ProgramName FROM #sp_who2 WHERE DBName = 'rio7_bch_test'
GO

DROP TABLE #sp_who2
GO

最佳答案

这听起来很像您有未正确释放的锁并阻止了 DDL 执行。

当语句挂起时,运行存储过程sp_who2

根据该过程的结果,您将知道哪个 session 正在阻止您的 DDL,然后您可以采取适当的操作。

关于Java 应用程序在调用PreparedStatement(针对 SQL Server DB)后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14899379/

相关文章:

sql - 创建全文索引错误

debugging - 有没有办法获取先前在 PostgreSQL 中作为给定事务的一部分执行的 SQL 语句的列表?

C# 我是否正确使用锁?

java - 如何在 Android 中检索雅虎联系人?

java - Spring MVC 3 - 使用 404 响应请求?

java - 使用不同的组件(功能)构建自定义 Java 对象

c# - 线程在没有锁定的情况下进行通信

java - 参数中带有通配符的不明确重载泛型方法

sql - 为每个 sql 查询输出指定标题

sql-server - SQL Server - 指定一天中的时间进行分组