MySQL之事务

事务概念

事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一 个整体。

一个完整的事务,绝对不是简单的 sql 集合,还需要满足如下四个属性(ACID):

原子性(Atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环 节。

一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。

隔离性(Isolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时 由于交叉执行而导致数据的不一致。

持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

innodb支持事务,而myisam不支持事务。

事务提交方式

事务的提交方式分为手动提交自动提交

手动提交是执行事务的时候,需要手动执行事务的begin和commit

自动提交是在执行单sql语句时,只需执行sql语句,mysql自动完成事务的begin和commit

事务的隔离级别

隔离性理解:为了保证事务执行过程中尽量不受干扰

读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。

读提交【Read Committed】 ::一个事务只能看到其他的已经提交的事务所做的改变。

可重复读【Repeatable Read】:它确保同一个事务,在执行中,多次读取操 作数据时,会看到同样的数据行。

串行化【Serializable】:: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突。它在每个读的数据行上面加上共享锁。

查看和设置隔离性

mysql> SELECT @@global.tx_isolation; --查看全局隔级别

mysql> SELECT @@session.tx_isolation; --查看会话(当前)全局隔级别

mysql> SELECT @@tx_isolation; --默认同上
设置隔离级别

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

MVCC(多版本并发控制)

3个隐藏字段

DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记录/最后一次修改该记录的事务ID

DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一 般在 undo log 中)

DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以 DB_ROW_ID 产生一 个聚簇索引

补充:实际还有一个删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了

undo日志

undo日志记录历史版本,保存历史数据。即保存更新前的记录。

Read View

当前读:读取最新的记录,就是当前读。增删改,都叫做当前读,select也有可能当前读,比如:select lock in share mode(共享锁), select for update

快照读:读取历史版本(历史版本存在undo日志里边),就叫做快照读。

Read View就是事务进行快照读操作的时候生产的读视图 (Read View),在该事务执行的快照读的那一刻,会生成数 据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增 的,所以最新的事务,ID值越大)。

Read View的本质是用来进行可见性判断的。即当我们某个事务执行快照读的时候,对该记录创建一个 Read View 读视图,把它比作条件,用来判断当前事务能够看到哪个版本的数据,既可能是当前最新 的数据,也有可能是该行记录的 undo log 里面的某个版本的数据。

m_ids; //一张列表,用来维护Read View生成时刻,系统正活跃的事务ID

up_limit_id; //记录m_ids列表中事务ID最小的ID(没有写错)

low_limit_id; //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1(也没有写错)

creator_trx_id //创建该ReadView的事务ID

RR和RC的本质区别

在RC隔离级别下,是每个快照读都会生成并获取最新的Read View

而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View

正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。

相关推荐
加油=^_^=4 分钟前
MySQL基础篇的补充
数据库·python·mysql
porkczr37 分钟前
oracle rac多个实例就相当于多个数据库系统程序
数据库·oracle
码java的秃头阿姨39 分钟前
SpringBoot设置mysql的ssl连接
spring boot·mysql·ssl
程序员大金43 分钟前
基于SpringBoot+Vue+MySQL的养老院管理系统
java·vue.js·spring boot·vscode·后端·mysql·vim
大白菜和MySQL1 小时前
mysql mha高可用集群搭建
数据库·mysql
QQ爱剪辑1 小时前
MySQL基础(13)- MySQL数据类型
数据库·mysql
后端小张2 小时前
Redis 执行 Lua,能保证原子性吗?
数据库·redis·缓存
离开地球表面_993 小时前
索引失效?查询结果不正确?原来都是隐式转换惹的祸
数据库·后端·mysql
lipviolet3 小时前
Redis系列---Redission分布式锁
数据库·redis·分布式
Zhen (Evan) Wang3 小时前
.NET 6 API + Dapper + SQL Server 2014
数据库·c#·.net