Skip to main content

用实例说明SQLite事务

SQLite&ACID

SQLite是一个事务数据库,所有更改和查询都是原子的、一致的、隔离的和持久的(ACID)。

SQLite保证所有事务都符合ACID,即使事务因程序崩溃、操作系统转储或计算机断电而中断。

SQLite事务语句

默认情况下,SQLite以自动提交模式运行。这意味着对于每个命令,SQLite都会自动启动、处理和提交事务。

要显式启动事务,请使用以下步骤:

首先,通过发出BEGIN transaction命令打开事务。

BEGIN TRANSACTION;

执行语句BEGIN TRANSACTION后,事务将打开,直到显式提交或回滚。

其次,发出SQL语句来选择或更新数据库中的数据。请注意,更改仅对当前会话(或客户端)可见。

第三,使用commit或commit TRANSACTION语句将更改提交到数据库。

COMMIT;

如果不想保存更改,可以使用ROLLBACK或ROLLBACK TRANSACTION语句进行回滚:

ROLLBACK;

SQLite事务示例

我们将为演示创建两个新表:accounts和account_changes。

accounts表存储有关帐号及其余额的数据。account_changes表存储帐户的更改。

首先,使用以下create TABLE语句创建accounts和account_changes表:

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
);

其次,在accounts表中插入一些示例数据。

INSERT INTO accounts (account_no,balance)
VALUES (100,20100);

INSERT INTO accounts (account_no,balance)
VALUES (200,10100);

第三,从accounts表中查询数据:

SELECT * FROM accounts;

第四,将1000从帐户100转移到200,并在单个事务中将更改记录到表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;

第五,从accounts表中查询数据:

SELECT * FROM accounts;

如您所见,余额已成功更新。

第六,查询账户变更表的内容:

SELECT * FROM account_changes;

让我们再举一个回滚事务的例子。

首先,尝试从账户100中扣除20000:

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'));

SQLite因余额不足而发出错误:

[SQLITE_CONSTRAINT]  Abort due to constraint violation (CHECK constraint failed: accounts)

但是,日志已保存到account_changes表中:

SELECT * FROM account_changes;

其次,使用ROLLBACK语句回滚事务:

ROLLBACK;

最后,从account#u changes表中查询数据,您将看到第3项变更不再存在:

SELECT * FROM account_changes;

在本教程中,您学习了如何通过使用BEGIN TRANSACTION、COMMIT和ROLLBACK语句来控制SQLite数据库中的事务来处理SQLite事务。