Oracle 数据库 SELECT... FOR UPDATE with autocommit on

Oracle database SELECT... FOR UPDATE with autocommit on

我正在 运行 此查询针对 Oracle 数据库 (11g)。该连接具有自动提交的默认值,即 'true'.

Connection con = driver.connect(url, properties);
String query = "SELECT EMPID, NAME FROM EMPLOYEE FOR UPDATE";

Statement statement = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet resultSet = statement.executeQuery(query);

SELECT... FOR UPDATE 声明它 "lock the selected rows so that other users cannot lock or update the rows until you end your transaction." 自动提交应该在查询执行后立即执行。但是锁一直存在,直到连接关闭。

(我在 sqlplus 上通过 运行 查询 select * FROM DBA_DML_LOCKS WHERE NAME = 'EMPLOYEE'; 检查了这一点。)

这是一个错误还是有人可以解释为什么? 提前谢谢你。

documentation所述:

the default is for a SQL statement to be committed when it is completed, not when it is executed. A statement is completed when all of its result sets and update counts have been retrieved. In almost all cases, however, a statement is completed, and therefore committed, right after it is executed

另一个documentation:

Enabling auto-commit may be more convenient, but gives you less control. For example, you have no option to roll back changes. In addition, some SQLJ or JDBC features are incompatible with auto-commit mode. For example, you must disable the auto-commit flag for update batching or SELECT FOR UPDATE syntax to work properly.

因此对于这种查询类型,您应该使用手动提交

我找到了这个文档。

FOR UPDATE clause 其中说:FOR UPDATE 子句的使用不是强制获取可更新的 JDBC 结果集。只要生成JDBC ResultSet的语句满足可更新游标的要求,生成JDBC ResultSet的JDBC语句就可以有并发模式ResultSet.CONCUR_UPDATABLE 使 ResultSet 可更新。

还有这个:Requirements for updatable cursors and updatable ResultSets

我假设您可以跳过您的案例中的 FOR UPDATE 子句。

请参阅此常见问题解答。使用 FOR UPDATE 时应关闭 AutoCommit。 http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-faq-090281.html#30_06

正如setAutoComit documentation所说:

The commit occurs when the statement completes. The time when the statement completes depends on the type of SQL Statement: - For DML statements, such as Insert, Update or Delete, and DDL statements, the statement is complete as soon as it has finished executing. - For Select statements, the statement is complete when the associated result set is closed. - For CallableStatement objects or for statements that return multiple results, the statement is complete when all of the associated result sets have been closed, and all update counts and output parameters have been retrieved.

因此,在您的情况下,锁将一直存在,直到您使用 ResultSet.close() explicitly or the ResultSet is closed automatically (see ResultSet.close() 关闭 ResultSet 以获取更多详细信息。

是的,你说得对 "it should be user's responsibility to manage transactions or auto commit"。