数据库事务:ACID
数据库事务:ACID
在任何一个与数据打交道的系统中,数据的准确性和一致性都是生命线。
🚀 场景:一次完整的部门裁撤
在我们的企业管理系统中,有部门表(tb_dept
)和员工表(tb_emp
)。现在,公司决定裁撤“教研部”,这不仅意味着要从部门表中删除该部门的记录,还必须同时删除该部门下的所有员工。这两个操作在逻辑上必须是一个不可分割的整体。
数据库准备
我们先用下面的SQL脚本来准备我们的演示环境:
表结构:
-- 数据库准备
-- 部门管理
create table tb_dept(id int unsigned primary key auto_increment comment '主键ID',name varchar(10) not null unique comment '部门名称',create_time datetime not null comment '创建时间',update_time datetime not null comment '修改时间'
) comment '部门表';-- 员工管理(带约束)
create table tb_emp (id int unsigned primary key auto_increment comment 'ID',username varchar(20) not null unique comment '用户名',password varchar(32) default '123456' comment '密码',name varchar(10) not null comment '姓名',gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',image varchar(300) comment '图像',job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管',entrydate date comment '入职时间',dept_id int unsigned comment '部门ID',create_time datetime not null comment '创建时间',update_time datetime not null comment '修改时间'
) comment '员工表';
初始数据:
insert into tb_dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()),(4,'就业部',now(),now()),(5,'人事部',now(),now());INSERT INTO tb_emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),(11,'luzhangke','123456','鹿杖客',1,'11.jpg',1,'2007-02-01',1,now(),now()),(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',1,'2008-08-18',1,now(),now()),(13,'fangdongbai','123456','方东白',1,'13.jpg',2,'2012-11-01',2,now(),now()),(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
⚙️ 事务的核心命令
在SQL中,我们使用三个核心命令来控制一个事务的生命周期。
-- 开启一个事务
START TRANSACTION;-- 业务操作1: 删除教研部
DELETE FROM tb_dept WHERE id = 2;
-- 业务操作2: 删除原教研部的所有员工
DELETE FROM tb_emp WHERE dept_id = 2;
DELETE FROM tb_emp WHERE dept_id == 2; -- 测试异常结果
-- 提交或者回滚前可以查一下数据库内容
select * from tb_emp;
select * from tb_dept;
-- 同时可以看一下idea或者可视化数据库软件中的表格数据 在提交之前事务是隔离的
-- 提交事务(如果一切顺利)
COMMIT;-- 或者 回滚事务(如果出现异常)
ROLLBACK;
START TRANSACTION
: 标志着一个事务的开始。在此之后的所有SQL操作都将被视为事务的一部分。COMMIT
: 提交事务。当所有操作都成功执行后,COMMIT
会将这些更改永久性地写入数据库。ROLLBACK
: 回滚事务。如果在事务执行过程中发生任何错误,ROLLBACK
会撤销自事务开始以来的所有更改,使数据库恢复到“原状”。
💎 事务的四大特性:ACID深度解析
ACID是衡量一个数据库事务是否可靠的黄金标准,它由四个单词的首字母组成。
1. A - 原子性 (Atomicity)
核心思想:“不可分割,要么全做,要么全不做”。
事务被视为一个不可分割的最小工作单元。事务中的所有操作,要么全部成功提交,要么在任意一步失败后,全部回滚。
在我们的示例中:
删除部门和删除员工这两个DELETE
操作被捆绑成了一个原子单元。如果删除员工的操作因故失败,那么删除部门的操作也会被自动撤销。数据库绝不会停留在部门已删,员工尚在的中间状态。
2. C - 一致性 (Consistency)
核心思想:“事务完成后,数据必须是合法的”。
事务必须使数据库从一个一致、有效的状态转移到另一个一致、有效的状态。它确保了数据的完整性约束不会被破坏。
在我们的示例中:
系统的一个重要业务规则是“员工必须属于一个已存在的部门”。
- 事务开始前:数据是一致的,所有员工都有合法的部门归属。
- 事务成功后:教研部和其所有员工都被删除了,剩下的员工也都有合法的部门归属,数据依然是一致的。
- 一致性确保了:绝不会出现员工的
dept_id
指向一个不存在的部门ID的情况。
3. I - 隔离性 (Isolation)
核心思想:“多个事务并发执行时,互不干扰”。
当多个事务同时访问数据库时,一个事务的执行不应被其他事务干扰。一个事务内部的中间状态对其他并发事务是不可见的。
在我们的示例中:
假设在我们的删除事务正在执行但尚未COMMIT
的瞬间,另一位管理员正在生成全公司的人员名单。隔离性确保了这位管理员的查询要么看到删除前的完整数据,要么等待我们的事务COMMIT
后看到删除后的数据,而绝不会看到教研部已被删除,但员工名单里还有教研部员工这种数据混乱的临时状态。
4. D - 持久性 (Durability)
核心思想:“一旦提交,永久有效”。
一旦事务被成功提交(COMMIT
),它对数据库中数据的改变就是永久性的,即使随后系统发生崩溃或断电等故障,提交的更改也不会丢失。
在我们的示例中:
一旦COMMIT
语句成功执行,教研部及其员工的删除记录就是永久性的。数据库通过事务日志(Transaction Log)等机制来保证,即使服务器立刻断电重启,这些数据也确定被删除了。
📊 总结
特性 | 英文 | 核心思想 | 在“部门裁撤”示例中的体现 |
---|---|---|---|
原子性 | Atomicity | 不可分割,全成功或全失败 | 删除部门和删除员工两个操作被捆绑执行 |
一致性 | Consistency | 保证数据的合法性和完整性 | 事务完成后,不会出现员工属于一个不存在的部门 |
隔离性 | Isolation | 并发事务之间互不影响 | 其他用户在删除过程中,看不到数据不一致的中间状态 |
持久性 | Durability | 提交后,更改永久生效 | COMMIT 成功后,即使系统崩溃,数据删除也是永久的 |