概要 :このチュートリアルでは、SQLiteトランザクションを使用してデータの整合性と信頼性を確保する方法を示します。
SQLite&ACID
SQLiteは、すべての変更とクエリがアトミックで、一貫性があり、分離され、耐久性のある(ACID)トランザクションデータベースです。
SQLiteは、トランザクションがプログラムのクラッシュ、オペレーティングシステムのダンプ、またはコンピューターの電源障害によって中断された場合でも、すべてのトランザクションがACIDに準拠していることを保証します。
- A トミック:トランザクションはアトミックである必要があります。これは、変更を小さな変更に分割できないことを意味します。トランザクションをコミットすると、トランザクション全体が適用されるかどうかが決まります。
- C onsistent:トランザクションは、データベースをある有効な状態から別の有効な状態に確実に変更する必要があります。トランザクションが開始され、データを変更するステートメントを実行すると、データベースに一貫性がなくなります。ただし、トランザクションがコミットまたはロールバックされる場合、トランザクションがデータベースの一貫性を維持する必要があることが重要です。
- 私 分離:セッションによって実行される保留中のトランザクションは、他のセッションから分離する必要があります。セッションがトランザクションを開始し、
INSERTを実行するとき またはUPDATEデータを変更するステートメント。これらの変更は現在のセッションにのみ表示され、他のセッションには表示されません。一方、トランザクションの開始後に他のセッションによってコミットされた変更は、現在のセッションには表示されないはずです。 - 耐久性:トランザクションが正常にコミットされた場合、電源障害やプログラムのクラッシュなどの状態に関係なく、変更はデータベース内で永続的である必要があります。逆に、トランザクションがコミットされる前にプログラムがクラッシュした場合、変更は持続しないはずです。
SQLiteトランザクションステートメント
デフォルトでは、SQLiteは自動コミットモードで動作します。これは、コマンドごとに、SQLiteがトランザクションを自動的に開始、処理、およびコミットすることを意味します。
トランザクションを明示的に開始するには、次の手順を使用します。
まず、BEGIN TRANSACTIONを発行してトランザクションを開きます コマンド。
BEGIN TRANSACTION;Code language: SQL (Structured Query Language) (sql)
ステートメントBEGIN TRANSACTIONを実行した後 、トランザクションは、明示的にコミットまたはロールバックされるまで開いています。
次に、SQLステートメントを発行して、データベース内のデータを選択または更新します。変更は現在のセッション(またはクライアント)にのみ表示されることに注意してください。
3番目に、COMMITを使用して、データベースへの変更をコミットします。 またはCOMMIT TRANSACTION ステートメント。
COMMIT;Code language: SQL (Structured Query Language) (sql)
変更を保存したくない場合は、ROLLBACKを使用してロールバックできます。 またはROLLBACK TRANSACTION ステートメント:
ROLLBACK;Code language: SQL (Structured Query Language) (sql) SQLiteトランザクションの例
2つの新しいテーブルを作成します:accounts およびaccount_changes デモンストレーションのために。
accounts テーブルには、口座番号とその残高に関するデータが格納されます。 account_changes テーブルにはアカウントの変更が保存されます。
まず、accountsを作成します およびaccount_changes 次のCREATE TABLEを使用してテーブルを作成します ステートメント:
CREATE TABLE accounts (
account_no INTEGER NOT NULL,
balance DECIMAL NOT NULL DEFAULT 0,
PRIMARY KEY(account_no),
CHECK(balance >= 0)
);
CREATE TABLE account_changes (
change_no INT NOT NULL PRIMARY KEY,
account_no INTEGER NOT NULL,
flag TEXT NOT NULL,
amount DECIMAL NOT NULL,
changed_at TEXT NOT NULL
);Code language: SQL (Structured Query Language) (sql)
次に、サンプルデータをaccountsに挿入します テーブル。
INSERT INTO accounts (account_no,balance)
VALUES (100,20100);
INSERT INTO accounts (account_no,balance)
VALUES (200,10100);
Code language: SQL (Structured Query Language) (sql)
第三に、accountsからデータをクエリします テーブル:
SELECT * FROM accounts;Code language: SQL (Structured Query Language) (sql)
第4に、アカウント100から200に1000を転送し、変更をテーブルaccount_changesに記録します。 単一のトランザクションで。
BEGIN TRANSACTION;
UPDATE accounts
SET balance = balance - 1000
WHERE account_no = 100;
UPDATE accounts
SET balance = balance + 1000
WHERE account_no = 200;
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(100,'-',1000,datetime('now'));
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(200,'+',1000,datetime('now'));
COMMIT;Code language: SQL (Structured Query Language) (sql)
第5に、accountsからデータをクエリします テーブル:
SELECT * FROM accounts;Code language: SQL (Structured Query Language) (sql)
ご覧のとおり、残高は正常に更新されています。
6番目に、account_changesの内容をクエリします テーブル:
SELECT * FROM account_changes;Code language: SQL (Structured Query Language) (sql)
トランザクションをロールバックする別の例を見てみましょう。
まず、アカウント100から20,000を差し引いてみてください:
BEGIN TRANSACTION;
UPDATE accounts
SET balance = balance - 20000
WHERE account_no = 100;
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(100,'-',20000,datetime('now'));Code language: SQL (Structured Query Language) (sql) バランスが不十分なため、SQLiteがエラーを発行しました:
[SQLITE_CONSTRAINT] Abort due to constraint violation (CHECK constraint failed: accounts)Code language: CSS (css)
ただし、ログはaccount_changesに保存されています テーブル:
SELECT * FROM account_changes;Code language: SQL (Structured Query Language) (sql)
次に、ROLLBACKを使用してトランザクションをロールバックします。 ステートメント:
ROLLBACK;Code language: SQL (Structured Query Language) (sql)
最後に、account_changesからデータをクエリします 表を見ると、変更番号3がもうないことがわかります。
SELECT * FROM account_changes;Code language: SQL (Structured Query Language) (sql)
このチュートリアルでは、BEGIN TRANSACTIONを使用してSQLiteトランザクションを処理する方法を学習しました。 、COMMIT 、およびROLLBACK SQLiteデータベースのトランザクションを制御するステートメント。