[[FrontPage]]へ~
-[[リファレンスガイド]]へ~
--[[Firebird SQLリファレンス]]へ~
----
*Firebird SQLリファレンス:SET TRANSACTION, COMMIT, ROLLBACK, SAVEPOINT, RELEASE SAVEPOINT [#vd634af1]
#contents
&name(set_transaction);
*SET TRANSACTION [#m7981d71]
動作オプションをつけてトランザクションを開始します。 SQL,DSQL,isql で使用できます。
**構文 [#r2dfa3a5]
SET TRANSACTION [NAME transaction]
[READ WRITE | READ ONLY]
[WAIT | NO WAIT]
[[ISOLATION LEVEL] {SNAPSHOT [TABLE STABILITY]
| READ COMMITTED [[NO] RECORD_VERSION]}]
[RESERVING <reserving_clause> | USING dbhandle [, dbhandle …]];
<reserving_clause> = table [, table …]
[FOR [SHARED | PROTECTED] {READ | WRITE}] [, <reserving_clause>]
※ DSQLで使用する場合、終端文字のセミコロンは不要です。 isql及びC/C++の埋め込みSQLでは行の終わりを示すために終端文字は必要です。
|引数|説明|h
|NAME transaction|トランザクションの名前を指定します。|
|~|・初期化されたホスト言語変数で指定できます。|
|~|・SQL でのみ使用できます。|
|READ WRITE|デフォルトです。テーブルの読書き両方を行います。|
|READ ONLY|トランザクションでは読込みのみ行います。|
|WAIT|デフォルトです。他のトランザクションとコンフリクトした場合、アクセスが待たされます。|
|NO WAIT|他のトランザクションとコンフリクトした場合、エラーとなります。|
|ISOLATION LEVEL|他トランザクションと同時にアクセスする場合のアイソレーションレベルの指定です。デフォルトは SNAPSHOT です。|
|RESERVING reserving_clause|トランザクションの開始時に、テーブルの予約を行います。|
|USING dbhandle [, dbhandle …]|データベースのアクセスを限定します。SQLのみで可能です。|
**詳細の説明 [#x4239c81]
SET TRANSACTION により、トランザクションを開始します。同時に、ロックがコンフリクト(衝突)した場合の動作やアクセス並列性の指定などデータベースのアクセス方法に関しても指定できます。
また、テーブルをアクセスするための事前予約も出来ます。これは、複数のデータベースをアクセスするアプリケーションでデータベースの部分的なアクセス制限のために非常に有効です。
重要 gpre -manualの指定を行ってプリプロセスしたアプリケーションの場合、常に明示的に SET TRANSACTION を指定して処理を始めます。
SET TRANSACTION の NAME 節で名前の指定を行わないと、デフォルト(無名)のトランザクションとなります。名前付きのトランザクションにすることにより、1つのアプリケーションで同時に複数のトランザクションを扱えます。すべてのトランザクション名は、ホスト言語変数によりコンパイル時に宣言します。これは DSQLではトランザクション名の動的な使用を妨げます。
デフォルトでのトランザクションのアクセス方法指定は READ WRITE となっています。もしも、読込みのみのトランザクションとしたい場合には、READ ONLY パラメータを指定してください。
もしも、同じ(同名)トランザクションにおいて同じデータの更新を行おうとした場合、最初の更新のみが成功します。この場合、更新を行ったトランザクションがコミットやロールバックされるまで、他のトランザクションはそのデータを更新したり削除したりすることは出来ません。WAIT動作指定(省略時デフォルト)では、このような場合はそれらのトランザクションの処理が待たされます。待たずにすぐにロックコンフリクトエラーを発生させたい場合は、NO WAIT パラメータの指定が必要です。
ISOLATION LEVEL(アイソレーションレベル)は、同じテーブルを同時にアクセスするトランザクション相互での影響の与え方を設定します。デフォルトでの ISOLATION LEVEL の指定は SNAPSHOT となっています。この場合、トランザクション開始以降に他の並列するトランザクションで行われた変更は、参照することが出来ません。
SNAPSHOT TABLE STABILIT を指定し、トランザクションがテーブルの読込みのみで変更を加えないことを保証することにより、他の読み込みを妨げないようにします。
READ COMMITTED を指定することにより、トランザクション中に他のトランザクションが行った最新の変更を参照出来るようになります。また、同じ行に対するコンフリクト(衝突)が発生しない限り、変更も行うことが出来ます。ただし、平走するトランザクションでの変更は、変更後にコミットが行われない限り参照できません。READ COMMITTED では、さらに2つのオプションパラメータが指定出来ます。
-NO RECORD_VERSION (省略時デフォルト)確定した最新の行を読み込めます。WAIT が同時に指定されて待ち状態になっている場合、コミットかロールバックで最新版が決まるまで待ち合わせ、その後再度読み込みを行います。
-RECORD_VERSION 未完のトランザクションにさらに新しくなる可能性がある行データがあっても、現在で最新となってる行のデータを読み込みます。
RESERVING節を指定してトランザクションを開始することにより、指定したテーブルへのアクセス方法のレベルを示すことが出来ます。トランザクションの開始時にテーブルアクセスの予約を行うことにより、デットロック発生の確率を減少させることが出来るかもしれません。
(訳注: アクセスレベルは、共有レベルの SHARED/PROTECTED とアクセス指定の READ/WRITE を指定できます。)
SQLでのみ使用可能な USING 節は、トランザクションでアクセスできるデータベースを限定することにより、システムリソースの消費を抑えます。
**用例 [#k709b53f]
例は、すべて埋め込みSQLでの例です。
-無名(デフォルト)のトランザクションを開始します。アイソレーションレベルには READ COMMITED を指定しています。もしも更新が衝突した場合、最初に変更を行ったトランザクションがコミットかロールバックするまで、処理が待たされます。
EXEC SQL
SET TRANSACTION WAIT ISOLATION LEVEL READ COMMITTED;
-名前付きトランザクションの例です。
EXEC SQL
SET TRANSACTION NAME T1 READ COMMITTED;
-トランザクション開始時に、テーブルを3つ予約してます。
EXEC SQL
SET TRANSACTION NAME TR1
WAIT
ISOLATION LEVEL READ COMMITTED NO RECORD_VERSION
RESERVING TABLE1, TABLE2 FOR SHARED WRITE,
TABLE3 FOR PROTECTED WRITE;
※以下はisqlでの例ですが、訳者が独自に付け足したものです。
-READ COMMITED の単純な例です。省略可能な句は省略してしまっています。
SET TRANSACTION READ COMMITTED;
-テーブル予約の例です。PROTECTED WRITE で予約していますので、トランザクション開始時レベルでのテーブルロック(表ロック)となります。複数のisqlを立ち上げて試してみてください。
SET TARNSACTION WAIT
ISOLATION LEVEL READ COMMITTED NO RECORD_VERSION
RESERVING TABLE1 FOR PROTECTED WRITE;
**参照 [#yd02d833]
[[COMMIT>#commit]] , [[ROLLBACK>#rollback]] , [[SET NAMES>#set_names]]
より詳細が知りたい場合は、Embedded SQL Guide の transaction の項を参照して下さい。
----
&aname(commit);
*COMMIT [#k9daa8dc]
トランザクションで生じたデータベースへの変更を反映させて、トランザクションを終了します。SQL,DSQL,isql で使用できます。
**構文 [#sbb727b1]
COMMIT [WORK] [TRANSACTION name] [RELEASE] [RETAIN [SNAPSHOT]];
※ DSQLで使用する場合、終端文字のセミコロンは不要です。 isql及びC/C++の埋め込みSQLでは行の終わりを示すために終端文字は必要です。
|引数|説明|h
|WORK|オプション指定できますが、これは他のRDBとの互換性のためだけに用意されています。|
|TRANSACTION name|コミットするトランザクションの名前です。省略するとデフォルトのトランザクションとなります。|
|RELEASE|旧バージョンInterBase?との互換性のために用意されています。|
|RETAIN [SNAPSHOT]|変更のコミットと、トランザクションコンテキストの保存を行います。|
**詳細の説明 [#iea3c10d]
COMMIT によりトランザクションが終了します。と同時に、
-すべての変更をデータベースに書き出します。
-以降の SNAPSHOT や READ COMMITED のトランザクションで変更後のデータが参照出来るようにします。
-RETAINを指定しない限り、オープンされたカーソルがあったらクローズします。
COMMIT で終了するトランザクションは、一般的に成功した場合となります。また、デフォルトのトランザクションを終了させるためにも、COMMIT または ROLLBACK を常に使用する必要があります。
※読込みのみと宣言して開始したトランザクションでデータベースの変更を行わなかった場合、COMMIT や ROLLBACK を使用してもデータベースには何も影響を与えません。しかし、以降のトランザクションでのパフォーマンスや、使用するシステムリソースのことを考えると、どちらかを使用して終了させするべきです。
''重要'' RELEASE は、古いバージョンのInterBase?との互換性を保つために用意されています。現在は、データベース接続を切断する場合は、DISCONNECTを使用して下さい。
**用例 [#za294a6e]
-isqlでの例です。デフォルトのトランザクションで行ったデータベースへの変更を、すべて反映させます。
COMMIT;
-埋め込み SQL で、名前付きトランザクションの場合の例です。
EXEC SQL
COMMIT TR1;
-埋め込みSQLで、トランザクションコンテキストを保持したまま変更のみを反映させます。
EXEC SQL
COMMIT RETAIN;
**参照 [#hc4a88a8]
DISCONNECT , [[ROLLBACK>#rollback]]
より詳細が知りたい場合は、Embedded SQL Guide の transaction の項を参照して下さい。
----
&aname(rollback);
*ROLLBACK [#v810a2db]
トランザクションで生じたデータベースへの変更を取り消して、トランザクションを終了します。SQL,DSQL,isql で使用できます。
この文書は、Firebird 1.5 リリースノートを基として内容を追加しています。
*構文 [#u897ed7a]
ROLLBACK [TRANSACTION name] [WORK] [RELEASE];
1.5以降のDSQLでは、セーブポイント指定が可能です。
ROLLBACK [WORK] TO [SAVEPOINT] <identifier>;
※ DSQLで使用する場合、終端文字のセミコロンは不要です。 isql及びC/C++の埋め込みSQLでは行の終わりを示すために終端文字は必要です
|引数|説明|h
|WORK|オプション指定できますが、これは他のRDBとの互換性のためだけに用意されています。|
|TRANSACTION name|ロールバックするトランザクションの名前です。省略するとデフォルトのトランザクションとなります。|
|RELEASE|旧バージョンInterBase?との互換性のために用意されています。データベース接続をすべて切断します。|
|TO [SAVEPOINT] <idenrifier>|ロールバックするセーブポイントをidenrifierで指定します。1.5以降のDSQLでのみ使用できます。|
**詳細の説明 [#y689876d]
ROLLBACK により、現在のトランザクションでのデータベースへの変更をすべて取り消して、トランザクションが終了します。これにより、プログラムとの接続が終了し、システムのリソースが解放されます。最後の ROLLBACK で RELEASE を指定すると、すべてにデータベースとの接続が切断されます。システムリソースをデータベースがリリースするまで、プログラムは待たされます。
TRANSACTION でトランザクション名を指定することにより、複数のトランザクションを使用するプログラムで、ロールバックを行うトランザクションを指定できます。省略した場合は、デフォルトのトランザクションがロールバックされます。 TRANSACTION 節は、DSQL では使用できません。
''重要'' RELEASE は、古いバージョンのInterBase?との互換性を保つために用意されています。現在は、データベース接続を切断する場合は、DISCONNECTを使用して下さい。
Firebird 1.5 以降では、DSQLにおいてロールバックするセーブポイントを指定することが出来ます。詳しくは、SAVEPOINTを参照して下さい。
**用例 [#l302cf0c]
-isqlでの例です。デフォルトのトランザクションをロールバックします。
ROLLBACK;
-埋め込みSQLプログラムで、名前付きトランザクションをロールバックします。
EXEC SQL
ROLLBACK TRANSACTION MYTRANS;
*参照 [#l16e396c]
[[COMMIT>#commit]] , DISCONNECT , [[SAVEPOINT>#savepoint]]
より詳細が知りたい場合は、Embedded SQL Guide の transaction の項を参照して下さい。
----
&aname(savepoint);
*SAVEPOINT [#m441093f]
トランザクションをロールバックするときに、任意の位置へロールバックするためのセーブポイントを指定します。 DSQL,isqlで使用できます。
この文書は、Firebird 1.5 リリースノートを基としています。
**構文 [#p1699b44]
SAVEPOINT <identifier>;
|引数|説明|h
|identifier|セーブポイントを識別するための識別名です。対応するROLLBACKで使用します。|
**詳細の説明 [#ed7313ab]
SAVEPOINT により、任意の時点へのロールバックを行うためのセーブポイントを指定できます。セーブポイントにより、エラー時などですべてをロールバックせずにその時点からの処理をすることが可能となるので、都合の良いエラー処理手順を実現できます。
トランザクションをあるセーブポイント時点へロールバックするには、拡張された ROLLBACK 文を使用してください。これにより、以下の処理が行われます。
-トランザクションでセーブポイント以降に行われた変更はロールバックされます。
-そのセーブポイント以降に作成されたセーブポイントを消去します。指定したセーブポイントや、それ以前に作成されたセーブポイントは消去されません。これにより、同じセーブポイントに何度も戻すことが可能です。
-セーブポイント以降に行われた、暗黙的・明示的な行ロックをすべて解除します。他トランザクションがセーブポイント後にロックした行をアクセスする場合、トランザクションがコミットかロールバックするまで待たされます。ロックされていない行に対するリクエストやアクセスは即座に処理できます。&br;※行ロックに関する本動作は、将来のバージョンで変更される可能性があります。
同一トランザクションで同じレコードの更新を何度も行った場合、セーブポイントのアンドゥログを格納するために、貴重なサーバのメモリを大量に消費してしまう場合があります。このようなときは、RELEASE SAVEPOINT 文によってセーブポイントのメンテナンスを行うことにより、消費されたシステムリソースを解放することが出来ます。
識別子を指定して RELEASE SAVEPOINT 文を実行すると、そのトランザクションの対応する SAVEPOINT が作成したセーブポイントが消去されます。
このとき、ONLY識別子の指定を省略すると、それ以降のセーブポイントがすべて消去されます。
RELEASE SAVEPOINT の構文に関しては、RELEASE SAVEPOINT を参照して下さい。
-内部セーブポイント
--デフォルトでは、データベースエンジンは自動的にトランザクションレベルのシステムセーブポイントをトランザクションのロールバックに使用します。ユーザーが ROLLBACK を実行すると、そのトランザクションで行われた変更はトランザクションレベルのセーブポイント時点に引き戻された後に、トランザクションのコミットが行われます。
--トランザクションレベルのセーブポイント下において、データベースボリュームへの変更が大量(10^4〜10^6程度のレコード数以上)に発生した場合、ある時点でデータベースエンジンは自動的にトランザクションレベルのセーブポイントを解放し、TIPメカニズムによるロールバック処理へとトランザクション処理方法を変更します。
--ユーザーがトランザクション下におけるレコードの大量変更が多いことが事前にわかっている場合には、TPB の isc_tpb_no_auto_undo フラグをを使用することにより、トランザクションレベルのセーブポイント作成の処理を禁止することが出来ます。
-PSQLに関して
--PSQLにはユーザーレベルのSAVEPOINTを実装していません。PSQL レイヤに実装すると、これを含んだプロシージャコールによりアトミックルールが破壊される場合があるためです。このような場合のFirebirdにおけるアンドゥ処理は、ストアドプロシージャ・トリガの例外処理により提供されます。
--SQL/PSQLは、自動的に内部セーブポイントを使用して実行されます。これにより、それらで記述されたSQLの実行結果は、すべての変更が成功して完了、すべての変更を取り消し、またはエラーのハンドルのいずれかとなります。各々の例外処理ブロックでは、自動的なシステムセーブポイントが個別に使用されます。
**用例 [#h3aa3ccc]
テーブルを新規作成して列を挿入し、セーブポイントの動作を確認する例です。1回目のSELECTでは0行、2回目のセレクトでは2行、3回目のセレクトでは1行が取得できます。
create table test (id integer);
commit;
insert into test values (1);
commit;
insert into test values (2);
savepoint y;
delete from test;
select * from test; -- returns no rows
rollback to y;
select * from test; -- returns two rows
rollback;
select * from test; -- returns one row
**参照 [#l3b10455]
[[ROLLBACK>#rollback]] , [[RELEASE SAVEPOINT>#release_savepoint]]
----
&aname(release_savepoint);
*RELEASE SAVEPOINT [#z9c2d8bf]
セーブポイントを削除します。 DSQL,isqlで使用できます。
この文書は、Firebird 1.5 リリースノートの情報を基として独自に作成しました。
**構文 [#y47c3fb6]
RELEASE SAVEPOINT <identifier> [ONLY];
|引数|説明|h
|identifier|既存のセーブポイントを識別するための識別名です。|
|ONLY|指定したセーブポイントのみを削除します。省略すると、そのセーブポイント以降のすべての無名セーブポイントを同時に削除します。|
**詳細の説明 [#b7445448]
RELEASE SAVEPOINT により、指定した既存のセーブポイントを削除し、そのために確保されていたシステムリソースを解放します。
同一トランザクションで同じレコードの更新を何度も行った場合、セーブポイントのアンドゥログを格納するために、貴重なサーバのメモリを大量に消費してしまう場合があります。このようなときは、RELEASE SAVEPOINT 文によってセーブポイントのメンテナンスを行うことにより、消費されたシステムリソースを解放することが出来ます。
識別子を指定して RELEASE SAVEPOINT 文を実行すると、そのトランザクションの対応する SAVEPOINT が作成したセーブポイントが消去されます。
このとき、ONLY識別子の指定を省略すると、それ以降のセーブポイントがすべて消去されます。
**参照 [#re4bcd17]
[[SAVEPOINT>#savepoint]]