我遇到了一个问题,我的交易似乎并没有真正开始,除非我发出一个似乎是交易值得的命令(最后一部分是猜想)。
下面我有一个用@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());
}
}
我不确定这是一个司机还是一个春天的东西,我倾向于司机的事情。