2017-08-27 48 views
0

H2データベースで行レベルのロックを使用しようとしています。 1回の接続でレコードレベルのロックを取得して解放する方法はありますか?H2データベースのロック解除

SELECT * 
FROM "locks" 
WHERE key = 'lock1' 
FOR UPDATE; 

SELECT * 
FROM "locks" 
WHERE key = 'lock2' 
FOR UPDATE; 

は、今私は、LOCK1をrelaseしたいのですが、LOCK2を保持し続けます。 「BEGIN TRANSACTION;」を挿入しようとしました。 lock2の前に、COMMITは両方のロックを解放します。

追加: サーバーデータベースにローカルキャッシュのようなH2を使用します。 目標は、プログラム間同期(java)を実装することです。 データは同期されません1:1、プログラムは何を保存するかを制御します。 FileChannelsはLinuxでは動作しませんが、ソケットは正常に動作しますが、私はそれらを醜い解決策にします。 タスク:

  1. サーバーとのデータベース同期。 1つのプログラムだけが同期を実行する必要があります。
  2. ログ書き込み;プログラムは2つのログファイルを使用し、1つから別のものに切り替えます。衝突を防ぐために、書き込み時間のためにファイルをロックする必要があります。
  3. 他にもあります。このとき

は、私は2つの方法

  1. たびに新しい接続を作成し、タスクの実行後にリリースを参照してください。接続確立には約600msかかる。
  2. テンポラリ・テーブルを使用する:CREATE AND DROP TEMPORARY TABLE tmp_lock1()。 2msかかります。問題:2つの接続があり、1番目のテンポラリテーブルを作成して突然終了すると(たとえばバグなど)、2番目のプログラムが動作するまでテーブルが存在します。

答えて

0

私はそれを自分で試したことがない、理論的には、あなたはにできるはずですにレコードを挿入、更新のためにそれを選択し、レコードを削除することでロックを解除。 012を使用しないでくださいMVCC - モードではない場合は、新しいレコードが別の接続で表示されません。

私は確信していませんが、達成したいと思うかもしれませんが、これはおそらく行く方法ではないかもしれませんが、ロックは解放され、もう一方は持続します。理論的には

0

あなたがそうのようなSAVEPOINTを使用することができるはずです:

が実際に
SELECT * FROM "locks" WHERE key = 'lock1' FOR UPDATE; 
SAVEPOINT beforeLock2; 
SELECT * FROM "locks" WHERE key = 'lock2' FOR UPDATE; 
ROLLBACK TO SAVEPOINT beforeLock2; 

それが動作しないとlock2行がロックされたままなので、私はトーマスの希望でそれを掲示していますバグかもしれませんそれを見るでしょう。

あなたが記述した内容から、lock1lock2の2つの接続を使用できない理由はありません。接続プールを使用すると、接続の作成にかかる時間は問題になりません。

関連する問題