1

私はちょうど今Teradataのロック機能を掘り下げ始めています、そしてグーグルはこれについての説明でかなり複雑です。うまくいけば、私はSEから非常に単純で合理化された答えを得ることができます。

TeradataのID列で多くの問題が発生した後、Oracleのシーケンスを模倣するメカニズムを作成することにしました。これを行うために、2つのフィールドを持つテーブルを作成しています。1つはテーブル名を保持し、もう1つは最後に使用されたシーケンスを格納します。次に、テーブル名をとるストアドプロシージャを作成します。手順内で、次のオプションを実行します。

  • シーケンステーブルから最後に使用したシーケンスを変数に選択します(select LastId from mydb.sequence where tablename = :tablename
  • 変数の値に1を追加して、値をインクリメントします
  • 増分値を使用するようにシーケンステーブルを更新します
  • シーケンス変数をプロシージャのOUTパラメータに戻し、.NETアプリでシーケンスされたIDにアクセスできるようにします。

これらのすべての操作が行われている間、すべての読み取りおよび書き込みアクセスに対してシーケンステーブルをロックして、プロシージャへの他の呼び出しが現在シーケンス中のテーブルをシーケンスしようとしないようにする必要があります。これは明らかに、同じシーケンスが同じテーブルに対して2回使用されないようにするためです。

これが.NETの場合、Sync Lock(VB.NET)またはlock(C#)を使用して、現在のスレッドが終了するまで他のスレッドがコードのブロックに入らないようにします。.NETでスレッドをロックするのと同じように、テーブルをロックする方法があるかどうか疑問に思っています。

4

1 に答える 1

1

トランザクションの行ハッシュロックに明示的なロックメカニズムを使用することを検討してください。

BEGIN TRANSACTION;

LOCKING ROW EXCLUSIVE
SELECT LastId + 1 INTO :LastID
FROM MyDB.SequenceCols
WHERE TableName = :TableName
  AND DatabaseName = :DatabaseName;

UPDATE MyDB.SequenceCols
SET LastId = :LastID
WHERE TableName = :TableName
  AND DatabaseName = :DatabaseName;

END TRANSACTION;

行ハッシュロックを使用すると、他のプロセスが他のテーブルに対してプロシージャを使用できるようになります。行レベルのロックを確実にするには、SequenceColsテーブルのプライマリインデックスを完全に修飾する必要があります。実際、SequenceColsテーブルのプライマリインデックスは、およびでUNIQUEである必要がDatabaseNameありTableNameます。

編集:

排他的な行ハッシュロックは、END TRANSACTIONが行ハッシュロックの所有者として処理されるまで、別のプロセスが行を読み取るのを防ぎます。

于 2012-07-31T16:46:53.600 に答える