私は、DataSource と Spring JdbcTemplate に Oracle Universal Connection Pool を使用しています。FE:
public class JdbcLock {
private static final Logger logger = LoggerFactory.getLogger(JdbcLock.class);
public static void main(String[] args) throws ClassNotFoundException, SQLException, InterruptedException {
PoolDataSource poolDataSource = PoolDataSourceFactory.getPoolDataSource();
poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
poolDataSource.setURL("jdbc:oracle:thin:@ldap://oraldap:389/dbtame,cn=OracleContext,dc=n,dc=b,dc=r");
poolDataSource.setUser("user");
poolDataSource.setPassword("password");
poolDataSource.setMaxPoolSize(8);
JdbcTemplate jdbcTemplate = new JdbcTemplate(poolDataSource);
jdbcTemplate.execute (
(ConnectionCallback<Object>) conn -> {
try (PreparedStatement psttm = conn.prepareStatement("select def from tab1 where id = 1 for update")) {
// boolean isAutoCommit = conn.getAutoCommit();
// if (isAutoCommit) {
// conn.setAutoCommit(false);
// }
psttm.setQueryTimeout(15);
try (ResultSet rset = psttm.executeQuery()) {
if (rset.next()) {
logger.info("Locked.");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
logger.error("InterruptedException", e);
}
}
} finally {
// conn.commit();
// if (isAutoCommit) {
// conn.setAutoCommit(true);
// }
}
} catch (SQLTimeoutException sqte) {
logger.error("ops1", sqte);
}
return null;
}
);
logger.info("UnLocked.");
Thread.sleep(5000);
logger.info("Finished.");
}
}
主なアイデア - 更新のために行のロックを取得しました。2 つの異なるプロセスから実行すると、jdbcTemplate.execute メソッドが終了した後 ("UnLocked" テキスト) にロックが解除されず、コードが終了した後 ("Finished." テキスト) にのみロックが解除されます。コードからコメントを削除すると(つまり、autoCommit = falseモードに切り替える)、すべて問題ありません。
これは JdbcTemplate のバグだと思います。または、Oracle 12.1.0.2 ucp ライブラリで... 私は正しいですか?