我正在使用 Spring 框架中的 JdbcTemplate。
数据库是Oracle。
简化代码:
void m() {
setAutocommit(false); // the same result with/without this line (by default: true )
JdbcTemplate jt;
...
String selectForUpdateLine = "SELECT X FROM T ... FOR UPDATE";
int x = jt.queryForList(selectForUpdateLine, objs, types, Smth.class).size();
...
addDelay(); // to be sure that I can simulate 2 consecutive SELECTs (just for test)
...
if ( x == 0 )
jt.update(insertLine, objs2, types2); // insert
else
jt.update(updateLine, objs2, types2); // update
}
如果我调用 m()
两次,它会执行:
选择 > 选择 > 插入/更新 > 插入/更新
但是我想要
选择 > 插入/更新 > 选择 > 插入/更新
我希望在第一个SELECT
之后有一个锁(基于SELECT ... FOR UPDATE
的优点),但是两个选择都被调用,所以更新/插入
效果不佳。
我还尝试使用 @Transactional
作为该方法,尝试创建一个同时包含 INSERT
和 UPDATE 的事务/INSERT
,但没有成功。
例如:
@Transactional(isolation=Isolation.SERIALIZABLE,propagation=Propagation.REQUIRES_NEW)
如何确定 SELECT
和 UPDATE/INSERT
将一起运行? (有/没有SELECT ... FOR UPDATE
、@Transactional
等)
最佳答案
您不能只发出一条 MERGE 语句,然后让数据库为您完成艰苦的工作,而不是先执行 SELECT FOR UPDATE,然后再执行 INSERT 或 UPDATE。您可能需要检查您要合并的表是否具有适当的唯一约束,例如
void m() {
JdbcTemplate jt;
...
jt.update(mergeLine, objs2, types2); // merge
}
关于java - JdbcTemplate SELECT ... FOR UPDATE - 无锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25445577/