SQLite Transaction 事务
事务 (Transaction
) 是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行
事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源
举个例子,A 向 B 转账 100 元,其实整个转账过程就是一个事务,要么转账成功了,A 的账户扣了 100 元,B 的账户增加了 100 元,要么转账失败,A 还是那么多钱,B 还是没钱,如果出现 A 扣了 100 元,B 的账户却没增加 100 元,那是要出问题的,是不?
事务,就是用来做这件事的,用来保证要么转账成功,要么转账失败
事务属性
事务可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
一般来说,事务是必须满足4个条件 ( ACID )
Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
-
原子性
一组事务,要么成功;要么失败回滚当作什么事都没发生
-
稳定性
有非法数据 (外键约束之类),事务撤回
-
隔离性
事务独立运行。一个事务处理后的结果,影响了其它事务,那么其它事务会撤回
事务的100%隔离,需要牺牲速度
-
可靠性
软、硬件崩溃后,SQLite 数据表驱动会利用日志文件重构修改
SQLite 事务
SQLite 默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作
因此要显式地开启一个事务务须使用命令 BEGIN TRANSACTION
SQLite 中可以使用下面的命令来控制事务
命令 | 说明 |
---|---|
BEGIN TRANSACTION | 开始事务处理。 |
COMMIT END TRANSACTION |
保存更改 |
ROLLBACK | 回滚所做的更改 |
事务控制命令只与 DML 命令 INSERT、UPDATE 和 DELETE 一起使用
他们不能在创建表或删除表时使用,因为这些操作在数据库中是自动提交的
BEGIN TRANSACTION 命令
事务 ( Transaction ) 可以使用 BEGIN TRANSACTION
命令或 BEGIN
命令来启动
BEGIN;
BEGIN TRANSACTION;
事务通常会持续执行下去,直到遇到下一个 COMMIT
或 ROLLBACK
命令
有个特殊情况是:在数据库关闭或发生错误时,事务处理会回滚
COMMIT 命令
COMMIT
命令用于把事务调用的更改保存到数据库中
COMMIT;
END TRANSACTION;
ROLLBACK 命令
ROLLBACK
命令是用于撤消尚未保存到数据库的事务
ROLLBACK;
实例
先运行下面的 SQLite SQL 语句创建测试数据
DROP TABLE tbl_employee; CREATE TABLE tbl_employee ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name CHAR(64) NOT NULL, age INTEGER NOT NULL, city CHAR(64), salary REAL ); INSERT INTO tbl_employee (name,age,city,salary) VALUES ('张三', 25, 'pek', 102400.00 ), ('李四', 18, 'shanghai', 88888.00 ), ('王五', 22, 'hangzhou', 22000.00 ), ('孙六', 32, 'pek', 32000.00 );
我们先使用 SELECT * FROM tbl_employee;
看一下表中的数据
id name age city salary ---------- ---------- ---------- ---------- ---------- 1 张三 25 pek 102400.0 2 李四 18 shanghai 88888.0 3 王五 22 hangzhou 22000.0 4 孙六 32 pek 32000.0
然后使用下面的语句开启一个事务
sqlite> BEGIN;
接着使用下面的语句插入一条数据 钱七
和 赵二
、删除数据 王五
、将 李四
的 city
改为 shenzhen
INSERT INTO tbl_employee (name,age,city,salary) VALUES ('钱七', 25, 'shanghai', 25000.00 ); DELETE FROM tbl_employee where name = '王五'; UPDATE tbl_employee SET city="shenzhen" WHERE name = "李四"; INSERT INTO tbl_employee (name,age,city,salary) VALUES ('赵二', 45, 'pek', 45800.00 );
然后使用 SELECT * FROM tbl_employee;
看一下表中的数据
sqlite> SELECT * FROM tbl_employee; id name age city salary ---------- ---------- ---------- ---------- ---------- 1 张三 25 pek 102400.0 2 李四 18 shenzhen 88888.0 4 孙六 32 pek 32000.0 5 钱七 25 shanghai 25000.0 6 赵二 45 pek 45800.0
数据好像有变更,但是这不是真的变更了,我们使用 ROLLBACK;
命令回滚事务
再使用 SELECT * FROM tbl_employee;
看一下表中的数据
id name age city salary ---------- ---------- ---------- ---------- ---------- 1 张三 25 pek 102400.0 2 李四 18 shanghai 88888.0 3 王五 22 hangzhou 22000.0 4 孙六 32 pek 32000.0
数据根本就没变
然后再执行下面的语句开启一个事物和执行一些操作
BEGIN; INSERT INTO tbl_employee (name,age,city,salary) VALUES ('钱七', 25, 'shanghai', 25000.00 ); DELETE FROM tbl_employee where name = '王五'; UPDATE tbl_employee SET city="shenzhen" WHERE name = "李四"; INSERT INTO tbl_employee (name,age,city,salary) VALUES ('赵二', 45, 'pek', 45800.00 );
这回我们使用 COMMIT;
提交事务
然后使用 SELECT * FROM tbl_employee;
看一下表中的数据
id name age city salary ---------- ---------- ---------- ---------- ---------- 1 张三 25 pek 102400.0 2 李四 18 shenzhen 88888.0 4 孙六 32 pek 32000.0 5 钱七 25 shanghai 25000.0 6 赵二 45 pek 45800.0
可以发现所有的操作都生效了