このトピックでは、ANSIセッション モードのトランザクションの意味に関するケース スタディについて説明します。Teradataセッション モード トランザクション処理のケース スタディも参照してください。
正常なANSIモードのトランザクションの例
次のトランザクションは、ANSIモードの正常なトランザクションの例です。
INSERT INTO employee SELECT * FROM employee; *** Insert completed. 26 rows added. |
この単一リクエストは、ANSIモードの明示的なトランザクションを開始します。 WRITEロックがemployeeに設定されます。 |
UPDATE employee SET department_number = 400 WHERE department_number = 401 ;DELETE FROM employee WHERE department_number = 401; *** Update completed. 7 rows changes. *** Delete completed. No rows removed. |
このリクエストは2つの文で構成されています。 WRITEロックはまだemployeeに設定されています。 |
SELECT * FROM employee WHERE department_number = 401; *** Query completed. No rows found. |
この単一文は、department_number 401のすべてのemployeeが直前のリクエストで削除されたことを確認するための検査です。 これはREAD (またはACCESS)ロックだけを必要とするSELECTリクエストですが、トランザクションはemployeeに対するWRITEロックの保持を続けることに注意してください。 |
COMMIT; *** COMMIT done. *** Total elapsed time was 1 second. |
このリクエストはすべての変更をコミットしてトランザクションを終了します。 すべてのロックは解放されて、一時ジャーナルはディクショナリから削除されます。 次のリクエストが入力されると、別のANSIトランザクションが開始します。 |
ANSIセッション モード エラーと失敗応答
ANSIトランザクションの実行中に、SQLエラー応答はロールバックを生じさせませんが、失敗応答は生じさせます。
次の例は、エラー応答がトランザクションをロールバックしないことを示しています。
INSERT INTO employee SELECT * FROM customer_service.employee; *** Insert completed. 26 rows added. |
このINSERT … SELECTリクエストは、ANSIモードのトランザクションを開始します。 |
SELECT * FRM employee; *** Error 3706 Syntax error; SELECT * must have a FROM clause. |
未処理のトランザクションで、構文解析ルーチンの問題はエラーであり、失敗ではありません。 直前のリクエストからの挿入は残り、すべてのロックは引き続き有効です。 |
SELECT * FROM employee; *** Query completed. 26 rows found. 9 columns returned. |
SELECT構文を訂正すると正常なリクエストが生成されて、最初のリクエストで挿入された行がその場所に残っていることが示されます。 トランザクションはまだコミットされていません。 |
SELECT * FROM employee WHERE emp_num = 1010; *** Error 5628 Column emp_num not found in Employee. |
意味解釈ルーチンの問題は、常にエラーとは限らず、常に失敗とも限りません。この例では、問題は失敗応答ではなくエラー応答を生じさせています。 最初のリクエストからの挿入は残り、すべてのロックは引き続き有効です。 |
SELECT * FROM employee; *** Query completed. 26 rows found. 9 columns returned. |
テーブルのすべての列の選択を繰り返すことにより、最初のリクエストで挿入された行が残っていることが証明されます。 トランザクションはまだコミットされていません。 |
COMMIT; |
最初のリクエストに挿入されたトランザクションと行がコミットされます。 |
SELECT * FRM employee; *** Failure 3706 Syntax error; SELECT * must have a FROM clause. |
未処理のトランザクションはないため、失敗応答が返されます。 上記で、トランザクションは正常に開かれたため、エラー応答が返されることに注意してください。 |
INSERT INTO employee SELECT * FROM customer_service.employee; *** Insert completed. 26 rows added. |
このINSERT … SELECTリクエストは、ANSIモードのトランザクションを開始します。 |
CREATE TABLE tbl_1 ( col_1, col_2 INTEGER); *** Error 3739 The user must give a data type for . |
未処理のトランザクションで、構文解析ルーチンの問題はエラーであり、失敗ではありません。 直前のリクエストからの挿入は残り、すべてのロックは引き続き有効です。 |
SELECT * FROM employee; *** Query completed. 26 rows found. 9 columns returned. |
テーブルのすべての列を選択することにより、最初のリクエストで挿入された行が残っていることが証明されます。 トランザクションはまだコミットされていません。 |
CREATE TABLE tbl_1 ( col_1 INTEGER, col_2 INTEGER); *** Failure 3802 Table ‘tbl_1’ already exists. |
この意味解釈ルーチンの問題は失敗応答を生じさせるので、トランザクションは終了します。 トランザクションはロールバックして、上記のコミット後にemployeeに挿入された行は削除されます。 |
SELECT * FROM employee; *** Query completed. No rows found. |
このリクエストは、ANSIモード トランザクションを開始します。 テーブルのすべての列を選択することにより、直前に挿入された行はすべて削除されたことが証明されます。 |
ANSIモードのトランザクション内でのDDLリクエストの設定
Teradataモードのトランザクションと同様に、1つのトランザクションには1つのDDLリクエストだけが存在可能で、それはCOMMITリクエストを除いて最後の順序のリクエストでなければなりません。
Teradataモードのトランザクションとは異なり、ANSIモードのトランザクションは、トランザクションをコミットする前に別のDDLリクエストを実行依頼しようとしてもロールバックしません。その代わりに、要求元がCOMMITリクエストまたはROLLBACK/ABORTリクエストのどちらかを発行するまで、エラー応答で応答を続けます。
CREATE TABLE table_3 ( col_1 INTEGER); *** Table has been created. |
この単一文のDDLリクエストは、ANSIモードのトランザクションを開始します。 現行トランザクションの境界内では、それ以降のリクエストは無効になります。 |
SHOW TABLE table_3; *** Error 3722 Only a COMMIT WORK or null statement is legal after a DDL Statement. |
単文リクエストは、現行トランザクションの境界内で直前のCREATE TABLEリクエストの後に別のリクエストを出すことはできないために、エラー応答を生じさせます。 トランザクションはロールバックしません。 |
COMMIT; *** COMMIT done. |
COMMITリクエストはトランザクションをコミットして、トランザクションは完了します。 |
SHOW TABLE table_3; CREATE MULTISET TABLE DB.table_3 ,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( col_1 INTEGER) PRIMARY INDEX ( col_1 ); |
このSHOW TABLEリクエストで新規のANSIトランザクションが開始して、table_3という名前のテーブルの作成に使用されたDDLが報告されます。 |
ANSIモードのトランザクションおよびDDL:複文リクエスト
Teradataモードのトランザクションの場合と同様に、ANSIセッション モードでは単一のリクエスト内にDDL文とDML文とを混在させることはできません。
同じ意味を持つ以下の複文リクエストおよびマクロは、どちらも失敗します。ANSIモードの失敗応答は、トランザクションをロールバックします。
SELECT * FROM table_1 ;SELECT * FROM table_2 ;CREATE TABLE table_5 ( col_1 INTEGER); *** Failure 3576 Data definition not valid unless solitary. Statement# 1, Info =0 CREATE MACRO mac_1 AS ( SELECT * FROM table_1; SELECT * FROM table_2; CREATE TABLE table_5 ( col_1 INTEGER);); *** Failure 3576 Data definition not valid unless solitary. Statement# 1, Info =0
異なるトランザクション構造に対するANSIモードのDELETEのパフォーマンス
DELETEリクエストを含むトランザクションを構造化する方法に応じて、テーブルから削除された行ごとに一時ジャーナルの項目を作成すること、またはトランザクション全体に対して1つだけ一時ジャーナルの項目を作成することができます。
以下のDELETEは単一リクエストで、トランザクションをコミットする別のリクエストが続きます。これは削除される行ごとに一時ジャーナル項目を書き込むので、特に大さなテーブルではそのパフォーマンスが低くなります。
DELETE FROM table_1; COMMIT;
以下の複文リクエストには、上記のトランザクションと同じ文が2つ含まれますが、複文リクエストとしてパッケージ化されているため、システムには両方の文が一緒に見えます。システムは、テーブルから削除される各行の一時ジャーナル エントリを書き込まず、その代わりに単一の一時ジャーナル エントリを書き込みます。複文リクエストのパフォーマンスは非常に良好です。
DELETE FROM table_1 ;COMMIT;
この最初のケースの場合、システムは次のリクエストが何であるか、またトランザクションのロールバックを準備する必要があることを把握しています。2つ目のケースの場合、システムは削除がコミットされることを確認することができ、そのためシステムはトランザクションをロールバックする必要がないことを把握しています。