2011-10-20 19 views
3

私は単純なJavaプログラムを作成しました。これは、トランザクションを開き、レコードを選択し、ロジックを実行してから更新します。レコードをロックして、SELECT ... FOR UPDATEを使用します。SELECT FOR UPDATEがJDBCとOracleで動作しない

プログラムはMS SQL Server 2005では正常に動作しますが、Oracle 10gではレコードはロックされていません。

理由は何ですか?

私は次のように接続を作成します。私は、Oracle SQL DeveloperのクライアントからSELECT..FORのUPDATEを実行すると、私はレコードがロックされていることがわかります

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

ので、私はそれがあるかもしれないと思っていますデータベースの問題ではなく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" 
+2

あなたが経験する問題について具体的にお聞かせください:何が​​うまくいかないのですか? –

+0

SELECT ... FOR UPDATEはレコードをロックしません。別のプログラムから同じレコードを同時に更新しようとすると、トランザクションがコミットまたはロールバックされるまでこれらのレコードがロックされていることがわかります(これはSQL Serverで実際に起こります)。 – Gep

答えて

3

申し訳ありませんが、私はこの現象を再現することはできません。 JDBCでSELECT ... FOR UPDATEクエリをどのように実行していますか?

私は、その中に次のデータを持つlocktestをテーブルを持っている:

 
SQL> select * from locktest; 

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

私も、このJavaクラスを持っている:私は、この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); 
    } 
} 

、それがいくつかの更新を行いテーブルを開き、寝る。それはトランザクションを開いたままにして、ロックを保持するようにスリープします。

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

これが寝ている間に、私は同時にSQL * Plusでテーブルを更新しよう:

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

この時点では、SQL * Plusは、私はJavaプログラムを殺すまでハングします。

+1

私はまた、rSet.updateRow()を配置する必要がありました。 udpateを動作させるためには、updateIntの後に。 – Codemwnci

+0

上記のコードを変更してTYPE_FORWARD_ONLY、CONCUR_READ_ONLYの結果セットを選択しましたが、他のクライアントが同じ行でSELECT ... FOR UPDATEを実行しないようにクエリをロックしました。 –

関連する問題