トランザクション
データベースの操作によっては,データベースコマンドの列を実行する必要があることがある.例えば2つの異なる表の情報を更新する場合等である.このようなときは,一つの更新を実行したら,もう一つも実行することが大変重要であることがある.一つしか更新しないと,データに不整合が生じる可能性がありからである.すべての操作が実行されるようにするには,データベーストランザクションが利用できる.また,操作の列の途中から戻るときにもトランザクションが使える.このチュートリアルでは,トランザクションの使い方について取り上げます.
このチュートリアルの例を実際に試してみて,記載の通りに動作しなかった場合は,「データベースの例の使用」で述べているように"DatabaseLink`DatabaseExamples`"パッケージを使ってデータベースをもとの状態に戻す必要があるかもしれない.
| SQLBeginTransaction[conn] | SQLトランザクションを開始する |
| SQLCommitTransaction[conn] | SQLトランザクションを永久にデータベースにコミットする |
| SQLRollbackTransaction[conn] | SQLトランザクションを終了する(データベースは変更しない) |
まずDatabaseLink をロードし, demoデータベースに接続する.
Needs["DatabaseLink`"];
conn = OpenSQLConnection["demo"];table = SQLTable["TEST"];
cols = {SQLColumn["X", "DataTypeName" -> "Integer"], SQLColumn["Y", "DataTypeName" -> "Integer"]};
SQLCreateTable[conn, table, cols];
SQLInsert[conn, "TEST", {"X", "Y"}, {5, 6}];SQLSelectを使って表TESTのデータを見る.行が1行ある.
SQLSelect[conn, "TEST", "ShowColumnHeadings" -> True]//TableFormSQLBeginTransactionでトランザクションを開始する.
SQLBeginTransaction[conn]SQLInsert[conn, "TEST", {"X", "Y"}, {61, 80}];
SQLInsert[conn, "TEST", {"X", "Y"}, {72, 5}];SQLSelect[conn, "TEST"]//TableFormSQLRollbackTransactionを使うと,データベースはトランザクションが始まる前の状態に戻る.挿入された2行はもうない.
SQLRollbackTransaction[conn];
SQLSelect[conn, "TEST"]//TableFormトランザクションはロールバックしたら閉じる.他のトランザクションが必要な場合は,新しいトランザクションを開始しなければならない.次の例では新しいトランザクションを開始し,2行挿入する.
SQLBeginTransaction[conn];
SQLInsert[conn, "TEST", {"X", "Y"}, {111, 141}];
SQLInsert[conn, "TEST", {"X", "Y"}, {190, 1}];SQLCommitTransactionを使ってデータを永久にコミットする.
SQLCommitTransaction[conn];
SQLSelect[conn, "TEST"]//TableFormトランザクションはコミットしたら閉じる.他のトランザクションが要求されたら,新しいトランザクションを開始しなければならない.一度トランザクションがコミットされたら,その後はロールバックできない.トランザクションはSQLSavepointを使って分割することができる.これにより,ロールバックで特定のセーブポイントまで戻ることができる.
次の例はトランザクションを開始し,データをいくつか挿入する.
SQLBeginTransaction[conn];
SQLInsert[conn, "TEST", {"X", "Y"}, {22, 11}];savepoint = SQLSetSavepoint[conn, "savepoint1"]SQLInsert[conn, "TEST", {"X", "Y"}, {17, 22}];
SQLSelect[conn, "TEST"]//TableFormSQLRollbackTransactionを使ってトランザクションをロールバックし,セーブポイントに戻る.
SQLRollbackTransaction[conn, savepoint]SQLSelect[conn, "TEST"]//TableFormSQLDropTable[conn, "TEST"];
CloseSQLConnection[conn];トランザクションの分離
複数の並列なユーザがいる場合にデータベースのトランザクションについて作業を行うと,データの読取りに関するさまざまな問題が生じる.これらの問題は「ダーティリード」,「反復不能読取り」,「ファントムリード」として知られている.これらの問題には2つの解決策がある.一つはトランザクションを分離するようにデータベース接続オプションを設定するというもので,もう一つはタイムスタンプの確認等,データについて別の確認を行うものである.どちらの方法も長所と短所がある.例えばデータベースオプションを設定すると,データベースの並列使用時のパフォーマンスを劣化させることがある.
これらの方法の実際の詳細はこのドキュメントの範囲外であるが,DatabaseLink にはトランザクションの分離の手助けとなる接続オプションを設定する方法がたくさんある.これはOpenSQLConnectionのTransactionIsolationLevelオプションで行う.このオプションはSetOptionsを使って既存の接続について設定することもできる.