2017-03-15 39 views
-1

私のpl \ sqlプロセスでは、 "alter table exchange parition .."の実行があります。 いくつかのテーブルにあります。oracleオブジェクトは存在しません

問題は、その操作中に他のユーザーがターゲット表にアクセスしようとする可能性があることです。

ORA-08103オブジェクトが存在しなくなりました。

「オブジェクトまたはビューが存在しません」のように同じではないと思います。私はエラー「オブジェクトがもう存在しない」ということだと思いません、プロセスがOK起動したときに来て、

し、Exchange(またはその他の操作)

側から来て、プロセス

BOすることはできません完了しました。

交換は非常に速いため、起こる可能性は非常に低いです。

しかし、この場合、解決する方法はありますか?このような状況を防ぐ方法は?

おそらく誰もテーブルに触れない場合にのみ交換を実行する方法はありますか?

ありがとうございました。

答えて

0

これは、セッション#1がカーソルを開いた後、そのカーソルから行をフェッチする前に、セッション#2がテーブル内のテーブルを変更したときに発生します。

ターゲット表にアクセスするために他のユーザーが使用しているコードを変更しない限り、交換が起こらないように簡単には考えられません。

LOCK TABLE mytable IN EXCLUSIVE MODEが完了するまでにSELECT文を待ちません、またそれはそうALTER TABLEが動作しませんしようとする前に排他ロックを取得し、開始から新しいSELECT文を防ぐことができます。

ALTER TABLESELECTと同時に発生しないようにするには、両方とも同じロックを取得する必要があります。比較的堅牢な方法は、DBMS_LOCKパッケージを使用してそのテーブルにロックを割り当てることです。ロック "mytablelock"を呼び出します。

次に、DBMS_LOCKを使用して、SELECTセッションは、進行する前に "mytablelock"の "shared"ロックを取得する必要があります。 alter tableセッションは、進行する前に "mytablelock"の "排他的"ロックを取得する必要があります。

このスキームでは、複数のSELECTセッションが互いに干渉することなく実行できるようになりますが、SELECTが実行されている間にALTER TABLEが実行されない可能性があります。

他のクエリから発行されたSELECTステートメントをSELECT FOR UPDATESに変更することは、堅牢ではありませんが、単純な方法です。しかし、それは不必要な待機やデッドロック・エラーの多くのレシピです。

+0

これは、このテーブルを選択するすべてのプロセスで、dbms_lockの操作を追加する必要があるということですか? – user2671057

+0

残念ながら、はい。 –

+0

それは私にとって大きな問題です。おそらく、ターゲットテーブルが現在使用中であるかどうかをチェックし、変更プロセスにスリープ状態を与える良い方法がありますか? – user2671057

関連する問題