我通过JDBC调用几个SQLServer 2008存储过程。
我希望所有这些proc调用都是同一事务的一部分。
在java方面,我有以下内容:
con.setAutoCommit( false );
boolean hasFailed = true;
try
{
... call PROC_1
... call PROC_2
con.commit( );
hasFailed = false;
}
finally
{
if ( hasFailed )
{
con.rollback( );
}
con.setAutoCommit( true );
}
在PROC_1中,我有一个交易保护,只有在没有交易有效的情况下才开始新交易。
通过检查@@ TRANCOUNT
的值来实现守卫declare @owns_transaction int = 0
begin try
if @@TRANCOUNT = 0
begin
begin transaction
set @owns_transaction = 1
end
... do work
if @owns_transaction = 1
begin
commit transaction
set @owns_transaction = 0
end
end try
begin catch
if @owns_transaction = 1
begin
rollback transaction
set @owns_transaction = 0
end
... handle error
end catch
然而,当我输入PROC_1时,@@ TRANCOUNT仍为0,因此它开始一个新的交易,我认为它可能会在以后产生一些可怕的后果。
我尝试使用XACT_STATE(),但它也返回0的结果,这意味着“当前请求没有活动用户事务。”并且根据这一点,我必须启动手动事务好。
我做错了吗?
顺便说一下,我认为SQLServer确实知道它在事务中,因为如果我在transaction
语句中添加一个名称,它会在rollback
中无法使用该名称回滚事务。这让我知道TOP-LEVEL事务不是在PROC_1中启动的,而是确实从JDBC开始。
答案 0 :(得分:1)
找到了一条路。
当你打电话
时结束con.setAutoCommit(false)
相当于在连接上设置IMPLICIT_TRANSACTIONS选项,如此
SET IMPLICIT_TRANSACTIONS ON;
然后,您可以在@@ OPTIONS函数的帮助下检查隐式事务状态:
if ((@@OPTIONS & 2) != 2) and (@@TRANCOUNT = 0)
begin
select 'No transaction'
end
else begin
select 'Already in transaction'
end