SELECT FOR UPDATE не работает с JDBC и Oracle - PullRequest
3 голосов
/ 20 октября 2011

Я написал простую Java-программу, которая открывает транзакцию, выбирает некоторые записи, выполняет некоторую логику и затем обновляет их. Я хочу, чтобы записи были заблокированы, поэтому я использовал SELECT ... FOR UPDATE.

Программа отлично работает с MS SQL Server 2005, но в Oracle 10g записи не заблокированы!

Есть идеи, почему?

Я создаю соединение следующим образом:

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

Если я выполняю SELECT..FOR UPDATE из клиента Oracle SQL Developer, я вижу, что записи заблокированы, поэтому я думаю, что это может быть проблема с драйвером 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"

1 Ответ

3 голосов
/ 20 октября 2011

Извините, я не могу воспроизвести это поведение. Как именно вы выполняете ваши SELECT ... FOR UPDATE запросы в JDBC?

У меня есть таблица, 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.

...