SELECT FOR UPDATE 不适用于 JDBC 和 Oracle

发布于 2024-12-10 17:02:11 字数 950 浏览 0 评论 0原文

我编写了一个简单的 Java 程序,它打开一个事务,选择一些记录,执行一些逻辑,然后更新它们。我希望锁定记录,因此我使用了 SELECT...FOR UPDATE。

该程序在 MS SQL Server 2005 中运行得非常好,但在 Oracle 10g 中记录没有被锁定!

知道为什么吗?

我创建连接如下:

Connection connection = DriverManager.getConnection(URL, User, Password);
connection.setAutoCommit(false);

如果我从 Oracle SQL Developer 客户端执行 SELECT..FOR UPDATE,我可以看到记录被锁定,所以我认为这可能是 JDBC 驱动程序的问题而不是数据库问题,但我在网上找不到任何有用的东西。

这些是我正在使用的 JDBC 驱动程序的详细信息:

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"

I've written a simple Java program, which opens a transaction, selects some records, does some logic and then updates them. I want the records to be locked so I used SELECT...FOR UPDATE.

The program works perfectly fine with MS SQL Server 2005, but in Oracle 10g the records are not locked!

Any idea why?

I create the connection as follow:

Connection connection = DriverManager.getConnection(URL, User, Password);
connection.setAutoCommit(false);

If I execute the SELECT..FOR UPDATE from Oracle SQL Developer client I can see that the records are locked, so I'm thinking it might be an issue with the JDBC driver rather than a database problem, but I couldn't find anything useful online.

These are the details of the JDBC driver I'm using:

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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一身仙ぐ女味 2024-12-17 17:02:11

抱歉,我无法重现此行为。您到底是如何在 JDBC 中运行 SELECT ... FOR UPDATE 查询的?

我有一个表 locktest ,其中包含以下数据:

SQL> select * from locktest;

         A          B
---------- ----------
         1          0
         2          0
         3          0
         4          0
         5          0

我还有这个 Java 类:

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 类时,它会对表进行一些更新,然后开始休眠。它会休眠,以便保持事务打开并因此保留锁。

C:\Users\Luke\stuff>java LockTest
Sleeping...

当它处于睡眠状态时,我尝试同时更新 SQL*Plus 中的表:

SQL> update locktest set b = 1 where a <= 3;

此时,SQL*Plus 会挂起,直到我终止 Java 程序。

Sorry, I cannot reproduce this behaviour. Exactly how are you running your SELECT ... FOR UPDATE queries in JDBC?

I have a table, locktest with the following data in it:

SQL> select * from locktest;

         A          B
---------- ----------
         1          0
         2          0
         3          0
         4          0
         5          0

I also have this Java class:

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);
    }
}

When I run this Java class, it makes some updates to the table and then starts sleeping. It sleeps so that it keeps the transaction open and hence retains the locks.

C:\Users\Luke\stuff>java LockTest
Sleeping...

While this is sleeping, I try to concurrently update the table in SQL*Plus:

SQL> update locktest set b = 1 where a <= 3;

At this point, SQL*Plus hangs until I kill the Java program.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文