共计 2187 个字符,预计需要花费 6 分钟才能阅读完成。
本篇内容主要讲解“MySQL 事务的 ACID 特性及并发问题实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“MySQL 事务的 ACID 特性及并发问题实例分析”吧!
一、事务的概念
一个事务是由一条或多条对数据库操作的 SQL 语句所组成的一个不可分割的单元,只有当事务中所有操作都正常执行完了,整个事务才会被提交给数据库,如果有部分事务处理失败,那么事务就要回滚到最初的状态,因此,事务要么全部执行成功,要么全部失败。
所以要记住事务几个基本概念,如下:
事务是一组 SQL 语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果,保证事务执行的原子操作。事务的所有 SQL 语句全部执行成功,才能提交(commit)事务,把结果写会磁盘上。事务执行过程中,有的 SQL 出现错误,那么事务必须要回滚(rollback)到最初的状态。
比如转账业务需要多条 SQL 语句共同完成,只有这些 SQL 都执行成功才算业务成功了。
事务处理有三个状态:
begin:开启一个事务要执行的全部 sql 语句都成功了,然后 commit 提交一个事务如果其中任何一条 SQL 语句由于停电、或者服务器出错,导致 SQL 执行异常,那事务就没有提交,事务会回滚(rollback),数据将恢复到事务开始前的状态
这是存储引擎来保证的(redo log 和 undo log 保证的)
MyISAM 存储引擎不支持事务,InnoDB 存储引擎支持事务、支持行锁。
用 show engines\G 查看当前数据库支持哪些存储引擎。
select @@autocommit; 查看对事务提交状态的设置
数据库引擎可以通过命令临时修改,或者通过配置文件永久修改。
如果说我们业务上涉及了事务,我们一般会在代码上控制这个变量,一般来说,我们的事务由多条 SQL 组成,要满足事务的原子性操作,所以我们设置为手动提交。业务都成功,则提交这个事务;如果业务中间出现失败,就回滚 1 个事务。
二、ACID 特性
每一个事务必须满足下面的 4 个特性:
事务的原子性(Atomic):事务是一个不可分割的整体,事务必须具有原子特性,及当事务修改时,要么全执行,要么全不执行,即不允许事务部分的完成。事务的一致性(Consistency):一个事务执行之前和执行之后,数据库数据必须保持一致性状态。数据库的一致性状态必须由用户来负责,由并发控制机制实现。就拿网上购物来说,你只有让商品出库,又让商品进入顾客的购物车才能构成一个完整的事务。(一致性不仅仅体现在事务里面,包括存储层引入 MySQL 为了提高热点数据的访问效率一般都会加一个缓存层 Redis 或者 Memery cache 对热点数据做缓存,这就涉及了缓存层和数据库 DB 层的数据一致性问题)事务的隔离性(Isolution):当两个或多个事务并发执行时,为了保证数据的安全性,将一个事务内部的操作与其他事务的操作隔离起来,不被其他正在执行的事务所看到,使得并发执行的各个事务之间不能互相影响。隔离级别:数据的安全性和事务的并发性。隔离越严格,安全性越高,并发性越低(就是并发控制,保证数据安全)事务的持久性(Durability):事务完成以后(事务 commit 成功),DBMS 保证它对数据库中的数据的修改时永久性的,即使数据库因为故障出错,也应该能够恢复数据。
MySQL 最重要的是日志,不是数据!
事务的 ACD 特性是由 MySQL 的 redo log 和 undo log 机制来保证的;I 隔离性是由 mysql 事务的锁机制来实现保证的。
三、事务并发存在的问题
事务处理不经隔离,并发执行事务时通常会发生以下问题:
脏读 (Dirty Read):一个事务读取了另一个事务未提交的数据。例如当事务 A 和事务 B 并发执行时,当事务 A 更新后,事务 B 查询读取到 A 尚未提交的数据,此时事务 A 回滚,则事务 B 读到的数据就是无效的脏数据(事务 B 读取了事务 A 尚未提交的数据)不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读到不同的数据。例如当事务 A 和事务 B 并发执行时,当事务 B 查询读取数据后,事务 A 更新操作更改事务 B 查询到的数据,此时事务 B 再去读该数据,发现前后两次读的数据不一样。(事务 B 读取了事务 A 已提交的数据)虚读(Phantom Read) 幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务 A 和事务 B 并发执行时,当事务 B 查询读取数据后,事务 A 新增或者删除了一条满足事务 B 查询条件的记录,此时事务 B 再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务 B 读取了事务 A 新增加的数据或者读不到事务 A 删除的数据)
脏读必须杜绝,因为事务没有 commit。在有些场景下,不可重复读和幻读是可以允许的(事务已经 commit),不一定非要杜绝(通过设置不同的隔离级别解决),由应用场景需求决定。
四、事务相关命令
select @@autocommit; 查看 MySQL 是否自动提交事务
0 表示手动提交事务,1 表示自动提交事务,设置事务提交方式为手动提交(只影响当前 session):
到此,相信大家对“MySQL 事务的 ACID 特性及并发问题实例分析”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!