有没有办法确定JDBC事务是否生效?

时间:2011-04-21 16:43:58

标签: sql-server jdbc

我通过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开始。

1 个答案:

答案 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