2017-07-19 3 views
0

私は、Teradataトランザクションでスナップショット分離に相当するものを実装しようとしています。 Oracleはこの種の分離をサポートしていますが、Teradataは(少なくとも私が認識しているバージョン14以前ではありません)。目標は、テーブルの内容を削除し、それをすべて再読み込みして他のユーザーがテーブルからの読み書きを禁止するプロシージャを作成することです。ストアドプロシージャ内の複数のステートメントでテーブルをロックする

私の理解によれば、オプティマイザは要求内のさまざまなテーブルロックについてすべて知ることができるbegin requestステートメントを見つけました。

私は以下の手順を書いていますが、.NETアプリケーションでスレッドロックをテストしていれば簡単に確実にデバッグする方法はわかりません(ブレークポイントの設定や他のスレッドの監視が簡単です)。 Teradataでは、私がここに書いたものが、プロシージャーの期間だけ正しくmydb.destinationtableをロックするかどうかはわかりません。これは正しいです?

編集:私は手順が機能することを追加します。 DELETE/INSERTを実行している間にSELECTを正しく実行できるだけです。

replace procedure mydb.myproc() 
begin 
    begin request 

    locking mydb.destinationtable for exclusive 
    delete mydb.destinationtable; 

    locking mydb.destinationtable for exclusive 
    insert into mydb.destinationtable 
    select * from mydb.sourcetable; 

    end request; 
end; 
+0

1.データを読み取るために、テーブルではなくビューを使用します。 2.ロード中にビューをドロップします。 3.読み込みが完了したらビューを再作成します。私が知る限り、すべてのロックを処理するmloadを使用することもできます。 – Andrew

+0

ETL中にロードされているテーブル(またはデータベース)に対する要求を拒否(または遅延)するためにTASMを使用しないのはなぜですか?理想的な解決策ではありませんが、ロックの分離に対処しますあるいは、エンド・ユーザーがキュー表のトークンにアクセスしようとする表にアクセスするビューで、ネストされたSELECTステートメントで定義されたキュー表と列を使用できますか。トークンがない場合、照会はQT_DELAYED状態になります。 –

+0

@RobPaller TASMを研究し、キューテーブルの例を見ると、多くの設定やボイラープレートが関わっているようです。彼らは仕事をしないと言っているのではなく、ストアドプロシージャ(つまり、BTEQなどではない)の中で、1)テーブルに排他ロックをかけ、2)複数のステートメントを実行するテーブル)、3)ロックを解除します。dnoethの答え*が表示されます。私のOPコードがそれを正確に実行することを確認しますが、まだわかりませんが一時的なジャーナリングのパフォーマンスが低下する可能性があります。 – oscilatingcretin

答えて

0

BEGIN REQUEST/END REQUEST F9を使用して、SQLアシスタントの両方の要求を提出同じであるいわゆるマルチ書要求(MSR)を作成します。

計画はF9でこれを実行して表示するには:

EXPLAIN 
locking mydb.destinationtable for exclusive 
delete mydb.destinationtable; 

insert into mydb.destinationtable 
select * from mydb.sourcetable; 

やBTEQ中:

EXPLAIN 
locking mydb.destinationtable for exclusive 
delete mydb.destinationtable 
;insert into mydb.destinationtable 
select * from mydb.sourcetable; 

はところで、第二ロックが冗長です。

しかし、。削除& InsSelを1つのトランザクションとして実行すると、両方とも一時的にジャーナリングされます。 多くはの要求よりも遅いです。

-- no BEGIN/END REQUEST 
insert into mydb.destinationtable_2 
select * from mydb.sourcetable; 

-- there's just a short dictionary lock 
-- all requests against the view submitted before the replace use the old data 
-- and all submitted after the new data 
replace view myview as 
select * from mydb.destinationtable_2; 

delete from mydb.destinationtable_1; 

今、あなたのSPのみ1 & 2(ベースを切り替えるためのロジックを必要とします:

これを行うには、より一般的な方法は、ビューのないテーブルの上にターゲット表とベースのアクセスの2つのコピーを使用することですon table [not] empty

+0

私は本当にテーブル/ビューの交換を避けたいと思います。ストアドプロシージャの実行中にテーブルに排他ロックを設定する方法はありませんか?冗長ロックまでは、DELETE中のみロックを置くとINSERTにもロックが適用されると言っていますか?トランジェントジャーナリングでは、トランザクションがコミットされるまで私のテーブルを排他的にロックできると同時に、同じトランザクションの下で別々のステートメントとして両方を実行する方法がありますか? – oscilatingcretin

+0

ソースを交換したくない理由は、オラクルのスナップショットの分離をエミュレートしたいからです。舞台裏で、オラクルは同じことをしているかもしれませんが、それは暗黙的です。 Teradataで手動でその種の分離をエミュレートすることは望ましくありません。 – oscilatingcretin

+0

MSRを実行すると、DEL&INS/SELの両方を1回の要求でオプティマイザに送信するため、オプティマイザは両方のステートメントが同じテーブルにアクセスし、最も制限の厳しいロックを適用することを認識します。とにかく倉庫ではないのはなぜですか?どのような種類のデータを処理していて、どのくらいの頻度でその手順を実行しますか? – dnoeth

関連する問題