什么是事务

事务时一组DML语句,这些语句在逻辑上存在相关性
这一组DML语句,要么全部成功,要么全部失败,时一个整体
MySQL提供一种机制,保证我们可以达到这种效果
事务就是由一组或多组sql语句组成的,用于处理操作量大,复杂度高的数据
一个完整的事务有以下四种属性:
原子性
一致性
隔离性
持久性
上面四种属性可以称为ACID



事务可以简化我们的编程模型,不需要我们考虑各种潜在错误喝并发问题
事务本质是为应用层服务的

事务常见的提交方式有两种
自动提交和手动提交





事务的正常操作
事务提交了就无法回滚了
只有提交前可以回滚

MySQL遇到异常情况会自动回滚
如果已经提交了,就算客户端崩溃了,MySQL数据也不会受影响




begin操作会自动更改提交方式
不会受MySQL是否自动提交的影响
自己begin就要自己commit









只要手动输入begin,事务就必须通过commit提交才能持久化,与是否设置set autocommit无关
事务可以手动回滚,如果操作异常,MySQL会自动回滚
对于InnoDB 每一条sql语句都默认封装成事务自动提交
没有设置保存点,也可以回滚,但是只能回滚到事务开始的时候
事务被提交了就不能回滚了

事务隔离级别
MySQL服务可能会在同时被多个客户端进程进行并发访问
为了避免不同事务互相影响的情况,需要隔离性
在事务场景中,隔离是必要的
隔离是对运行中的事务,进行互相隔离
是为了在事务运行中,不会出现互相干扰
根据影响程度的不同,会划分隔离级别
隔离级别分为:
读未提交
读提交
可重复读
串行化



使用select @@global.tx_ioslation,可以查看全局隔级别
使用select @@session.tx_ioslation,可以查看会话(当前)全局隔离别
使用select @@tx_ioslation,同上

设置:
一般不推荐修改隔离级别



读未提交几乎没有加锁,虽然效率高,但是问题太多了,不推荐使用
一个事务还没有提交,另一方就能立刻看到
一个事务在执行中读到另一个事务没有提交的内容,这个行为叫脏读


由于该事务在运行时会存在不可重复读问题
(在读取过程中,数据发生了变动,导致在同一个事务中,同样的读取,在不同的时间段,会读取到不同的值)


一个终端在对应事务中insert数据时,另一个中孤单的事务周期中,没有影响


串行化会对所有操作全部枷锁,不会有问题,但是效率很低
如果一个终端中存在数据更新或其他操作,会被阻塞,知道另一个终端的事务提交


隔离级别越高,安全性约到,数据库的并发性能越低
不可重复读的重点时修改和删除:相同的条件,读取的值不同
幻读的重点在于新增:相同的条件,读取的记录数不同

事务的一致性
事务的一致性通过原子性来保证
一致性和用户的业务逻辑强相关,由用户决定

数据库的并发场景
数据库的并发场景由三种:
1.读-读
2.读-写
3.写-写

读-写
MVCC
多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制
MySQL可能会面临处理多个事务的状况,因此要对多个事务进行管理
MySQL会为每一个事务分配一个单向增长的事务id
可以根据id判断事务到来的先后


MySQL内部的相关缓冲区中,保存相关的数据,完成各种判断操作,然后再合适的时候,将相关数据刷新到磁盘当中
undo log就是MySQL中的一段内存缓冲区,用来保存日志数据






读取最新的数据,叫做当前读
增删改都是当前读,需要加锁
快照读是读取历史版本,不受加锁限制,就可以并行执行了,提高了效率
read view
Read View是事务进行快照读时产生的读视图
在事务执行快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护当前活跃事务的id
这个id时递增的





read view是事务可见性的一个类,不是事务创建出来,就会有read view





read view形成的时机不同,会影响事务的可见性
事务中快照读的结果很依赖该事务首次出现快照读的地方
某个事务中首次出现快照读,决定该事务后续快照读结果的能力
