データベーストランザクションは、データベース管理システム(または類似のシステム)内でデータベースに対して実行される作業単位を表し、他のトランザクションとは独立して一貫性のある信頼性の高い方法で処理されます[ 1 ]。トランザクションは一般的に、データベース内のあらゆる変更を表します。データベース環境におけるトランザクションには、主に2つの目的があります。
データベース管理システムにおいて、トランザクションとは、複数の操作から構成される場合もある、単一の論理演算または作業単位のことです。データベース内で一貫した方法で行われる論理計算はすべてトランザクションと呼ばれます。例えば、ある銀行口座から別の銀行口座への送金が挙げられます。この場合、送金する金額を一方の口座から差し引き、同じ金額をもう一方の口座に加算するという一連の処理が必要です。
データベース トランザクションは、定義上、アトミック(完全に完了するか、まったく影響がないかのどちらかでなければならない)、一貫性(データベース内の既存の制約に準拠しなければならない)、分離性(他のトランザクションに影響を与えてはならない)、および永続性(永続ストレージに書き込まれなければならない) を備えている必要があります。[ 2 ]データベースの実務者は、データベース トランザクションのこれらの特性を、ACIDという頭字語でよく参照します。
データの整合性を最優先事項とするデータベースやその他のデータストアは、データの整合性を維持するためにトランザクションを処理する機能を備えていることが多い。単一のトランザクションは、1つ以上の独立した処理単位から構成され、それぞれがデータベースやその他のデータストアに対して情報の読み書きを行う。このような場合、すべての処理がデータベースやデータストアを一貫した状態に保ったまま終了するようにすることが重要となる。
複式簿記の会計システムからの例は、取引の概念を説明する際によく用いられます。複式簿記では、すべての借方には対応する貸方を記録する必要があります。例えば、食料品を購入するために100ドルの小切手を切った場合、取引に基づく複式簿記システムでは、この単一の取引を記録するために、次の2つの仕訳を記録する必要があります。
トランザクションシステムでは、両方のエントリが成功するか、両方のエントリが失敗するかのどちらかになります。複数のエントリの記録をアトミックなトランザクション単位として扱うことで、システムは記録されたデータの整合性を維持します。つまり、借方が記録されたのに、それに対応する貸方が記録されない、あるいはその逆といった状況は発生しません。
トランザクションデータベースは、括弧で囲まれたデータベース操作 (begin-commit) に対してACID 特性を提供するDBMSです。トランザクションは、同時更新や障害が発生した場合でも、データベースが常に一貫した状態であることを保証します。 [ 3 ]トランザクション内のすべての書き込み操作は、すべてか無かの効果を持ちます。つまり、トランザクションが成功してすべての書き込みが有効になるか、そうでなければ、データベースはトランザクションの書き込みが一切含まれない状態になります。トランザクションはまた、同時トランザクションの効果が分離レベルと呼ばれる特定の保証を満たすことを保証します。最も高い分離レベルは直列化可能性であり、同時トランザクションの効果がそれらの直列 (つまり順次) 実行と同等であることを保証します。
最もモダンなリレーショナルデータベース管理システムはトランザクションをサポートします。NoSQLデータベースは、同時更新やアクセスが発生した場合でもデータの一貫性を保証するために、トランザクションをサポートすることに加えてスケーラビリティを優先します。
データベースシステムでは、トランザクションは1つ以上のデータ操作ステートメントとクエリで構成され、それぞれがデータベース内の情報を読み書きします。データベースシステムのユーザーは、データの一貫性と完全性を非常に重要視しています。単純なトランザクションは通常、 SQLなどの言語でトランザクションにラップされ、次のようなパターンを使用してデータベースシステムに発行されます。
トランザクションコミット操作は、トランザクションの範囲内で行われたデータ操作のすべての結果をデータベースに永続化します。トランザクションロールバック操作は、トランザクションの範囲内で行われたデータ操作の部分的な結果をデータベースに永続化しません。部分的なトランザクションをデータベースにコミットすると、データベースが矛盾した状態になるため、いかなる場合もコミットすることはできません。
マルチユーザーデータベースは、内部的にトランザクションを保存および処理しますが、多くの場合、トランザクションIDまたはXIDを使用します。
トランザクションを実装する方法は、上記で説明した単純な方法以外にも複数あります。たとえば、ネストされたトランザクションは、新しいトランザクション(つまりサブトランザクション)を開始するステートメントを含むトランザクションです。マルチレベルトランザクションは、ネストされたトランザクションのバリアントであり、サブトランザクションは階層化されたシステムアーキテクチャの異なるレベルで実行されます(たとえば、1 つの操作がデータベースエンジンレベルで、1 つの操作がオペレーティングシステムレベルで実行されます)。[ 4 ]トランザクションのもう 1 つのタイプは、補償トランザクションです。
トランザクションはほとんどのSQLデータベース実装で利用可能ですが、その堅牢性にはばらつきがあります。例えば、MySQLはバージョン3.23からトランザクションをサポートし始めましたが、InnoDBストレージエンジンはバージョン5.5以前はデフォルトではありませんでした。それ以前に利用可能だったストレージエンジンであるMyISAMはトランザクションをサポートしていません。
トランザクションは通常、コマンドを使用して開始されますBEGIN(ただし、SQL 標準では が指定されていますSTART TRANSACTION)。システムがCOMMITステートメントを処理すると、トランザクションは正常に完了して終了します。ROLLBACKステートメントによってもトランザクションを終了し、以降に実行されたすべての作業を元に戻すことができますBEGIN。トランザクションの開始時に自動コミットが無効になっていた場合、トランザクションの終了時に自動コミットが再び有効になります。
トランザクションの分離レベルは、個々のトランザクション操作だけでなく、グローバルにも設定できます。最高レベル( READ COMMITTED)では、トランザクション開始後に実行された操作の結果は、トランザクションが終了するまで他のデータベースユーザーには表示されません。最低レベル(READ UNCOMMITTED)は、高い同時実行性を確保するために時折使用されることがありますが、このような変更はすぐに反映されます。
リレーショナルデータベースは、従来、固定サイズのフィールドとレコードを持つテーブルで構成されています。オブジェクトデータベースは、可変サイズのブロブで構成され、シリアル化可能であったり、 MIMEタイプを組み込んでいる場合があります。リレーショナルデータベースとオブジェクトデータベースの基本的な共通点は、開始とコミットまたはロールバックです。
トランザクションを開始すると、データベースのレコードまたはオブジェクトは、読み取り専用または読み書き可能のいずれかの状態でロックされます。その後、読み取りと書き込みが可能になります。トランザクションが完全に定義されると、変更はアトミックにコミットまたはロールバックされ、トランザクションの終了時に不整合が発生しないようにします。
データベースシステムは、複数のノード間でデータにアクセスするトランザクションとして分散トランザクション[ 5 ]を実装します。分散トランザクションは、複数のノード間でACID特性を強制し、データベース、ストレージマネージャ、ファイルシステム、メッセージングシステム、その他のデータマネージャなどのシステムを含む場合があります。分散トランザクションでは、通常、トランザクションのすべての部分がすべての関連システムに適用されるように、すべてのプロセスを調整するエンティティが存在します。さらに、これらの環境内でのストレージ・アズ・ア・サービス(StaaS)の統合は非常に重要です。StaaSは、可用性、拡張性、ACID特性が異なるさまざまなクラウドベースのデータストアクラスに対応できる、事実上無限のストレージリソースプールを提供します。この統合は、クラウドベースのデータストア全体に展開されたデータ集約型アプリケーションで、可用性の向上、応答時間の短縮、コスト効率の向上を実現するために不可欠です。[ 6 ]
Linux用のNamesys Reiser4ファイルシステム[ 7 ]は トランザクションをサポートしており、Microsoft Windows Vista以降では、Microsoft NTFSファイルシステム[ 8 ]がネットワークを介した分散トランザクションをサポートしています。Warp Transactional Filesystem (WTF) [ 9 ]など、よりデータ整合性の高いファイルシステムに関する研究も行われています。
トランザクションとは、データベースが単一の作業単位とみなす操作のことです。データベースの一貫性を保つためには、トランザクションが完全に完了する必要があります。たとえば、ある銀行口座から別の銀行口座に送金する場合、送金はあなたの口座から引き落とされ、第三者の口座に追加される必要があります。両方のステップが実行されない限り、トランザクションが完了したとはみなされません。