除非我做修改,否则交易无法启动

时间:2015-11-28 05:38:49

标签: java sql-server spring jdbc transactions

我遇到了一个问题,我的交易似乎并没有真正开始,除非我发出一个似乎是交易值得的命令(最后一部分是猜想)。

下面我有一个用@Transaction属性修饰的方法,它是公共的,它是通过spring代理调用的。我使用Microsoft的JDBC驱动程序版本4.2连接到SQL Server。并且获得应用程序锁定,如果我尝试获取应用程序锁定,然后做一些值得交易的交易似乎没有开始。我根据返回的错误代码(-999)猜测这一点,这与不在交易中是一致的。

这段代码在我的其他项目中完美运行,但我们所做的不仅仅是抓取应用锁。

以下是方法(忽略这样一个事实,即在获取后它会立即丢失应用程序锁定)

@Transactional
public Boolean getAppLock(String lockString, Integer timeoutMilliseconds) {
    try {
        Session session = entityManager.unwrap(Session.class);

        int result = session.doReturningWork(connection -> {
            int execResult = -1;

            // Works if I add this line
            // connection.prepareStatement("insert into foo (baz) values('bar')").execute();

            // This line works also, which is stupid, cause it doesn't even update anything
            // connection.prepareStatement("update foo set baz = baz where id = 1231241").execute();
            try (PreparedStatement statement = connection.prepareStatement("declare @i int; exec @i = sp_getapplock ?,?,?,?; select @i;")) {

                statement.setString(1, lockString);
                statement.setString(2, "Exclusive");
                statement.setString(3, "Transaction");
                Integer timeout = timeoutMilliseconds == null ? 0 : timeoutMilliseconds;
                statement.setInt(4, timeout);

                try (ResultSet resultSet = statement.executeQuery()) {
                    resultSet.next();

                    // Complains about not being in a transaction, unless
                    // I have a random statement that seems transaction worthy
                    execResult = resultSet.getInt(1);
                } catch (Exception ex) {
                    logger.error("Failed getting the result set from the app lock", ex);
                }
            } catch (Exception ex) {
                logger.error("Error executing statement sp_getapplock", ex);
            }
            return execResult;
        });

       // see return codes here (https://msdn.microsoft.com/en-us/library/ms189823.aspx), 0+ is good, < 0 is bad

        return result >= 0;
    }
    catch (Exception ex){
        throw new RuntimeException(ex.getMessage());
    }
}

我不确定这是一个司机还是一个春天的东西,我倾向于司机的事情。

0 个答案:

没有答案