SELECT FOR UPDATE not working with JDBC and Oracle
我写了一个简单的Java程序,它打开一个事务,选择一些记录,执行一些逻辑,然后更新它们。我希望记录被锁定,所以我使用SELECT ... FOR UPDATE。
该程序可与MS SQL Server 2005完美配合,但在Oracle 10g中,记录未锁定!
知道为什么吗?
我按如下方式创建连接:
1 2 | Connection connection = DriverManager.getConnection(URL, User, Password); connection.setAutoCommit(false); |
如果我从Oracle SQL Developer客户端执行SELECT..FOR UPDATE,则可以看到记录已锁定,因此我认为这可能是JDBC驱动程序的问题,而不是数据库的问题,但我无法在网上找不到有用的东西。
这些是我正在使用的JDBC驱动程序的详细信息:
1 2 3 4 5 6 7 8 9 10 | Manifest-Version: 1.0 Implementation-Vendor: Oracle Corporation Implementation-Title: ojdbc14.jar Implementation-Version: Oracle JDBC Driver version -"10.2.0.2.0" Implementation-Time: Tue Jan 24 08:55:21 2006 Specification-Vendor: Oracle Corporation Sealed: true Created-By: 1.4.2_08 (Sun Microsystems Inc.) Specification-Title: Oracle JDBC driver classes for use with JDK14 Specification-Version: Oracle JDBC Driver version -"10.2.0.2.0" |
对不起,我无法重现此行为。究竟如何在JDBC中运行
我有一个表
1 2 3 4 5 6 7 8 9 | SQL> select * from locktest; A B ---------- ---------- 1 0 2 0 3 0 4 0 5 0 |
我也有这个Java类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import oracle.jdbc.OracleDriver; import java.sql.*; public class LockTest { public static void main(String[] args) throws Exception { DriverManager.registerDriver(new OracleDriver()); Connection c = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:XE","user","password"); c.setAutoCommit(false); Statement stmt = c.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rSet = stmt.executeQuery( "SELECT a, b FROM locktest FOR UPDATE"); while (rSet.next()) { if (rSet.getInt(1) <= 3) { rSet.updateInt(2, 1); } } System.out.println("Sleeping..."); Thread.sleep(Long.MAX_VALUE); } } |
当我运行此Java类时,它将对表进行一些更新,然后开始hibernate。它处于hibernate状态,以使事务保持打开状态,从而保留了锁。
1 2 | C:\\Users\\Luke\\stuff>java LockTest Sleeping... |
这是在hibernate时,我尝试同时更新SQL * Plus中的表:
1 | SQL> update locktest set b = 1 where a <= 3; |
这时,SQL * Plus挂起,直到我杀死Java程序。