![](/img/trans.png)
[英]Why does Java not support retrieval of exceptions from try/catch lost when an exception is thrown from finally?
[英]Why does TRY CATCH successfully update rows on SSMS but not when run from Tomcat application?
我有一个 TSQL 程序,在 Azure 的 SQL 上。 这是一个最小的可重现示例。
CREATE PROCEDURE MyPROC
AS
BEGIN
BEGIN TRY
SELECT 1/0
END TRY
BEGIN CATCH
UPDATE error_log SET error_desc='test'
END CATCH
END
当直接从 SSMS 运行时, error_log
会成功更新。
从我的 Tomcat 应用程序(使用 Tomcat 用户)运行时,将执行该过程但error_log
未更新。
Tomcat 使用以下 Java 代码执行程序
DBConnection dbConn = DBConnection.getInstance();
Connection conn = null;
try {
conn = dbConn.getConnection();
conn.setAutoCommit(false);
CallableStatement stmt = conn.prepareCall("{CALL MyPROC}");
stmt.execute();
result = stmt.getInt(fields.size());
if (result == DBProcedures.RESULT_FAILED) { // error
conn.rollback();
} else { // ok
conn.commit();
}
} catch (SQLException e) {
result = DBProcedures.RESULT_FAILED;
try {
conn.rollback();
} catch (SQLException e1) {
System.out.println("Exception on " + this.toString() + " " + e.toString());
}
System.out.println("Exception on " + this.toString() + " " + e.toString());
} finally {
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
System.out.println("Exception on " + this.toString() + " " + e.toString());
}
dbConn.returnConnection(conn);
}
我检查了 Tomcat 用户对error_log
表有权限。
我错过了什么? 我了解并非所有错误都被TRY CATCH
,并且我了解有时事务无法执行任何会生成写入操作的 Transact-SQL 语句。 但是,我的示例似乎不属于这两个类别中的任何一个。 此外,它确实在 SSMS 下工作。
这是由于auto_commit
设置为 off 造成的,这意味着驱动程序执行命令SET IMPLICIT_TRANSACTIONS ON;
您可以在这个 fiddle中看到这一点。
要绕过它,您可以先显式回滚原始事务。 理想情况下,您还应该使用XACT_ABORT
来防止挂起事务,并使用THROW;
重新抛出原始错误。
CREATE PROCEDURE MyPROC
AS
BEGIN
SET XACT_ABORT ON;
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK;
UPDATE error_log SET error_desc = 'test';
THROW; -- only if you want the error to propagate back to Tomcat
END CATCH;
END;
老实说,我不建议使用BEGIN CATCH
来记录错误,因为并非所有错误都可以捕获。 而是使用 SQL 服务器错误日志或 XEvent session 来记录错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.