2011-07-28 2 views
0

私は複数の仕事の種類があります。下記の11gシナリオのロックで「選択したFOR UPDATE」を使用する方法は?

CREATE TABLE EMP (EMPNO NUMBER(10) PRIMARY KEY, JOB_TYPE VARCHAR2(20), PROCESSED VARCHAR2(3), 
THREAD NUMBER(4)); 

INSERT INTO EMP VALUES (7125, 'MANAGER', 'NO', NULL); 
INSERT INTO EMP VALUES (7250, 'MANAGER', 'NO', NULL); 
INSERT INTO EMP VALUES (7400, 'MANAGER', 'NO', NULL); 
INSERT INTO EMP VALUES (7445, 'CLERK', 'NO', NULL); 
INSERT INTO EMP VALUES (7550, 'CLERK', 'NO', NULL); 
INSERT INTO EMP VALUES (7600, 'CLERK', 'NO', NULL); 
INSERT INTO EMP VALUES (7945, 'CLERK', 'NO', NULL); 
INSERT INTO EMP VALUES (7965, 'ANALYST', 'NO', NULL); 
INSERT INTO EMP VALUES (7970, 'ANALYST', 'NO', NULL); 
INSERT INTO EMP VALUES (7975, 'ANALYST', 'NO', NULL); 
INSERT INTO EMP VALUES (7980, 'ANALYST', 'NO', NULL); 
INSERT INTO EMP VALUES (7985, 'ANALYST', 'NO', NULL); 
INSERT INTO EMP VALUES (7990, 'ANALYST', 'NO', NULL); 

COMMIT; 

ここで、お互いを待たずに各ジョブタイプを処理する複数の並列スレッドを生成したいとします。行が処理されると、スレッドは処理済み(PROCESSEDをYESに、THREADをスレッド番号に更新)とマークし、次の行に移動します。

最後に、表は次のようになります。

EMPNO JOB_TYPE PROCESSED THREAD 
7125 MANAGER  YES   1 
7250 MANAGER  YES   1 
7400 MANAGER  YES   1 
7445 CLERK  YES   2 
7550 CLERK  YES   2 
7600 CLERK  YES   2 
7945 CLERK  YES   2 
7965 ANALYST  YES   3 
7970 ANALYST  YES   3 
7975 ANALYST  YES   3 
7980 ANALYST  YES   3 
7985 ANALYST  YES   3 
7990 ANALYST  YES   3 

スレッド1処理MANAGER行、スレッド2処理店員行およびスレッド3処理ANALYST行。私はの線に沿って考えています

スレッド1が入ってくる、BULKは、すべてMANAGERの行をフェッチし、それらをロックし、それらを処理します。 スレッド2が入って、すべてのMANAGER行をBULK FETCHしようとします。ロックされているので、次のJOB_TYPEにスキップします。 BULKはCLERK行をFETCHし、それらをロックして処理します。 スレッド3が入って、MANAGERとCLERKがロックされているとみなされ、ANALYST行に移動します。

また、各スレッドはNOとマークされた行を処理することにも注意してください。したがって、あるスレッドが処理を完了してロックを解放した後、もう1つのスレッドはPROCESSED = YESとマークされているため、同じ行を再処理すべきではありません。

私のような環境では、ジョブタイプごとに数百のジョブタイプと数千の行があります。並列スレッドの数は、任意の時点でデータベースで使用されているリソースの量に応じて、DBAによって外部的に制御されます。

私がFOR UPDATE SKIP LOCKEDについて見つけた1つの警告は、カーソルを開いたときとは対照的に(pl/sqlでカーソルを使用している場合)行を実際にフェッチするときにロックが取得されることです。

重要な基準の1つは、2つのスレッドが1つのジョブタイプを処理しないようにすることです。

これはすべて意味がありますか?

AQを使用しないことについての私のコメントは、データベースにAQを設定するためには追加の権限が必要だということですが、SKIP LOCKEDはこれを実現できるように思われます。 11gではAQをSKIP LOCKEDで置き換えることはできないと言っていますか?

+0

今後コードをフォーマットしてください。 –

+0

@トニー:どんな形式のものを期待しているのか教えていただけますか? –

+0

私はちょうどあなたのためにしたフォーマットと同じですが、元に戻しました!コードブロックを選択し、{}というラベルの付いたボタンを押すと、4つのスペースだけインデントされます。これにより、それはきちんとフォーマットされます。 –

答えて

0

あなたはデータを処理したいスレッドを誰が生成するのですか?あなたは実際に行をロックする必要がありますか、またはあなたが思っていることが必要になるだけですか?

Oracleは、作業をチャンクに分割してスケジューラを使用して、これらのチャンクを異なるスレッドに割り当てることを容易にするDBMS_PARALLEL_EXECUTE packageを提供します。あなたの場合、CREATE_CHUNKS_BY_SQLを使用して、JOB_TYPEごとに1つのチャンクを作成できます。

+0

私はjavaでデータを処理するスレッドを使用しています。 –

+0

@kedar - ちょうど明確になるので、あなたはスレッドを生成する気にしますか?データベースでスレッドを生成させたくないのですか? –

+0

問題は、thread1が「更新用」を使用していくつかの行をロックするときです。同じ時間にthread2が同じ行を読み込もうとします。スレッド1が計算を完了すると、それは "PROCESSED" = "YES"とマークされ、thread2も同じことをしています。だから私は "SKIP LOCKED"と "NOWAIT"に遭遇したので上記のシナリオにふさわしいでしょうか? –

関連する問題