昨天复习 MySQL 事务相关知识,顺道总结了下,分享给大家。
本文主要介绍 MySQL 事务的概念、ACID 特性以及事务隔离级别。
希望对 MySQL 新手同学有所启发,MySQL 老鸟们也可作为复习参考。
话不多说,正文开始…
文末附:《史上最全MySQL 学习路线图》。
1. 什么是事务?
事务是数据库操作的一个基本单位,它由一系列的数据库操作组成,这些操作要么全部成功执行,要么全部失败回滚。
事务的目的是确保数据库操作的一致性和完整性。
例如:
张三向李四转账10元,过程是这样的:
- 张三账户余额扣除10元
- 李四账户增加10元
步骤一和步骤二是一组事务。
任何一个步骤执行失败,数据就需要回滚。张三和李四的账户余额都不能改变。
只有当两个步骤都执行成功了,这才是具有原子性的事务操作。
2. 事务的四大特性(ACID)
MySQL 事务的 ACID 属性是指:原子性、一致性、隔离性和持久性。
一般来说,事务是必须满足这 4 个条件(ACID)。
下面对每个属性进行简要说明:
2.1 原子性(Atomicity)
原子性指一个事务中的操作要么全部执行成功,要么全部回滚失败,不存在部分执行成功的情况。
事务中的任何一步操作失败,整个事务都将回滚到初始状态。
例如:
当从一个银行账户转账到另一个账户时,要么转账成功并更新两个账户的余额,要么转账失败并保持原始状态。
2.2 一致性(Consistency)
一致性指事务将数据库从一种一致状态转换为另一种一致状态。
在事务执行期间,数据库始终保持一致的状态,不会因为部分操作的执行而导致数据不一致。
在事务开始之前和结束之后,数据库必须满足一定的约束条件。
例如:
当向数据库插入一条订单记录(商品数量、客户信息)时,要保证订单的相关数据完整且符合业务规则。
2.3 隔离性(Isolation)
隔离性是指多个并发事务之间的操作互相隔离,每个事务都好像在独立运行,不受其他事务的影响,从而避免数据的干扰和冲突。
不同的事务隔离级别,提供了不同程度的隔离性。
例如:
在高并发情况下,多个用户同时查询同一商品的库存数量,需要保证每个用户看到的库存数量是准确且独立的。
2.4 持久性(Durability)
持久性指一旦事务提交成功,其所做的数据修改将永久保存在数据库中,即使发生系统故障或重新启动,也能够恢复到提交后的状态。
例如:
当用户成功下单并支付后,订单信息和支付记录需要被持久化保存,以防止数据丢失或不可恢复。
3. 事务的使用
3.1 显示事务
显示事务是由开发人员显式地编写事务控制语句来控制事务的开始和结束。
示例:
银行转账中,可以使用显示事务来确保从一个账户扣除金额,并将金额存入另一个账户,这是一个原子性的操作。
BEGIN TRANSACTION; UPDATE Account SET Balance = Balance - 100 WHERE AccountID = 'A'; UPDATE Account SET Balance = Balance + 100 WHERE AccountID = 'B'; COMMIT;
3.2 隐式事务
隐式事务是由数据库管理系统自动管理的事务,不需要显式地编写事务控制语句。
通常,每个 SQL 语句都被视为一个隐式事务。
示例:
张三在某多买一件衣服。在这个过程中,数据库管理系统会自动为每个数据库操作创建一个隐式事务:
INSERT INTO Orders (OrderID, CustomerID, ProductID, Quantity) VALUES ('123456', '张三', '789', 1); UPDATE Inventory SET Quantity = Quantity - 1 WHERE ProductID = '789';
4. 事务的状态
活动的(active)
部分提交的(partilly committed)
失败的(failed)
中止的(aborted)
提交的(committed)
5. 事务并发问题
在事务并发执行的情况下,可能会出现以下问题:
5.1 脏读
脏读指在一个事务中读取了另一个事务未提交的数据,这将导致读取到不一致或无效的数据。
5.2 幻读
幻读指在一个事务中多次查询同一数据时,由于其他事务插入了新的数据,导致前后查询结果不一致。
5.3 不可重复读
不可重复读指在一个事务中多次读取同一数据,但在这个过程中,其他事务修改或删除了该数据,导致前后读取结果不一致。
6. MySQL 事务隔离级别
针对上述并发问题,MySQL 使用了四种事务的隔离级别,用来隔离并发运行各个事务,使得它们相互不受影响,即 MySQL 事务的隔离性。
MySQL 事务隔离级别定义了事务之间的隔离程度、以及并发访问数据库时的行为。
MySQL 的四种事务隔离级别分别是:读未提交、读已提交、可重复读、串行化。
6.1 读未提交(READ UNCOMMITTED)
读未提交级别具有最高的并发性能,适用于对数据一致性要求较低的场景。
在该隔离级别下,事务可以读取其他事务未提交的数据,可能会导致脏读,即读取到了未经验证的临时数据。
6.2 读已提交(READ COMMITTED)
读已提交级别是大多数数据库默认的隔离级别。
在该隔离级别下,事务只能读取已经提交的数据,避免了脏读问题。
但是,可能会出现不可重复读问题,即在同一个事务中多次读取同一数据,但每次读取的结果不一致。
6.3 可重复读( REPEATABLE READ)
可重复读级别适用于对数据一致性要求较高的场景。
在该隔离级别下,事务在执行期间能够多次读取同一数据,并保持一致的结果。
事务期间,其他事务对数据的修改不会影响到当前事务,避免了不可重复读问题。但是,可能会出现幻读问题,即在同一个事务中多次执行同一个查询,但结果集不同。
6.4 串行化(SERIALIZABLE)
在该隔离级别下,事务按照串行的方式执行,确保每个事务之间互不干扰。避免了脏读、不可重复读和幻读问题,但牺牲了并发性能。串行化级别适用于对数据一致性要求非常高的场景。
选择隔离级别需要根据业务需求和并发访问情况来决定。同时,还要注意避免长时间的事务和锁定,以避免对系统性能造成负面影响。
在并发的环境下,每个隔离级别都有其特定的行为和影响。
这个部分本文就不展开探讨了,后续系列文章中会专门写一篇。
另外,关于 MySQL 的完整学习路线,需要的话,我主页的第 1 篇文章查看。
总结
通过本文,我们掌握了 MySQL 事务核心知识,包括MySQL 事务的概念、ACID 属性、事务隔离级别等。
我是爱分享的程序员宝妹儿,谢谢关注 Java面试题宝。
如果觉得不错,请【点赞+转发+关注】一键三连支持下。
—end—
[…] 详解篇: MySQL事务特性及隔离级别,8张图带你彻底吃透 […]
[…] 详解篇: MySQL事务特性及隔离级别,8张图带你彻底吃透 […]