我试图掌握一个与 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