系列文章传送门:
文章目录:
一、什么是事务
二、事务的特性
三、MySQL使用事务
四、InnoDB 事务的ACID如何保证
五、事务的隔离级别
一、什么是事务
数据库事务是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)。一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成。事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。
以银行转账为例:账户转账是一个完整的业务,最小的单元,不可再分------也就是说银行账户转账是一个事务:
update t_act set balance=balance - 400 where actno=1;
update t_act set balance=balance + 400 where actno=2;
以上两台DML语句必须同时成功或者同时失败。最小单元不可再分,当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下;这个记录是在内存中完成的;当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步。若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务。
汇总:1.针对DML语句的
2.是一个操作序列(包含的是多条语句)
3.一个不可分割的原子操作:要么全部执行成功,要么全部执行失败
- commit: 提交,即将数据永久进行了更改
rollback: 回滚,回到执行事务之前的状态
二、事务的特性
事务是由一组SQL语句 组成的逻辑处理单元,它的ACID特性如下:
(一)原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
(二)一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
(三)隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
(四)持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
三、MySQL使用事务
(一)自动提交策略
MySQL默认已经开启自动提交,我们可以通过对应的设置来开启或者关闭自动提交。
查看事务的类型:select @@autocommit;
关闭自动提交:set global autocommit=0;
(二)开启事务流程
开启事务,并结束事务,结束可用commit或者rollback。
PS:可用savepiont设置隔离点,用(rollback to 点的名)回到指定点。
begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
rollback;
四、InnoDB 事务的ACID如何保证
(一)基本概念
- redo log:重做日志 ib_logfile0~1 50M , 轮询使用
- redo log buffer:redo内存区域
- ibd:存储 数据行和索引
- buffer pool:缓冲区池,数据和索引的缓冲
- LSN : 日志序列号
- WAL : write ahead log 日志优先写的方式实现持久化
- 脏页: 内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.
- CKPT:Checkpoint,检查点,就是将脏页刷写到磁盘的动作
- TXID: 事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务
- 磁盘数据页,redo文件,buffer pool,redo buffer
(MySQL 每次数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者LSN一致数据库才能正常启动)
(二)重做日志redo log
1、作用:在事务ACID过程中,实现的是"D"持久化的作用。对于AC也有相应的作用
2、redo的日志文件:iblogfile0 iblogfile1
3、redo buffer:数据页的变化信息+数据页当时的LSN号
4、LSN:日志序列号 磁盘数据页、内存数据页、redo buffer、redolog
5、redo的刷新策略:刷新当前事务的redo buffer到磁盘,还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘。
(三)undo 回滚日志的作用
- 在事务ACID过程中,实现的是"A" 原子性的作用
- 另外CI也依赖于Undo
- 在rolback时,将数据恢复到修改之前的状态
- 在CSR实现的是,将redo当中记录的未提交的时候进行回滚.
- undo提供快照技术,保存事务修改之前的数据状态.保证了MVCC,隔离性,mysqldump的热备
五、事务的隔离级别
(一)脏读
指一个事务读取了另外一个事务未提交的数据。
(二)不可重复读
指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
例如:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据并修改数据。那么,在第一个事务的两次读数据之间。由于另一个事务的修改,那么第一个事务两次读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。
(三)虚读/幻读
指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
例如:事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据 称为幻读。
PS:幻读和不可重复读的区别:
- 不可重复读:是同一条SQL查询的内容不同(被修改了)
- 幻读:查询的结果条数不同(增加了、或者删除了记录)
(四)事务的隔离级别
为了处理这些问题,SQL标准定义了以下几种事务隔离级别
-
Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
-
Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)
-
Read committed:可避免脏读情况发生(读已提交)。
-
Read uncommitted:最低级别,以上情况均无法保证。(读未提交)
查询当前事务隔离级别:select @@tx_isolation
设置事务隔离级别:set transaction isolation level + 隔离级别
PS:事务隔离级别是通过Mysql中锁和MVCC实现的。
都看到这里了,创作不易,大家点个赞走啦!!- ̗̀(๑ᵔ⌔ᵔ๑)