事务ACID特性

Atomic(原子性)

所有语句作为一个单元全部成功执行或全部取消。

Consistent(一致性)

如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。

在事务内看到的数据状态都是一样的。

Isolated(隔离性)

事务之间不相互影响。

Durable(持久性)

事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

例子:

事务的控制语句

START TRANSACTION(或 BEGIN):显式开始一个新事务

SAVEPOINT:分配事务过程中的一个位置,以供将来引用或回滚

COMMIT:永久记录当前事务所做的更改

ROLLBACK:取消当前事务所做的更改

ROLLBACK TO SAVEPOINT:取消在 savepoint 之后执行的更改

RELEASE SAVEPOINT:删除 savepoint 标识符

SET AUTOCOMMIT:为当前连接禁用或启用默认 autocommit 模式

自动提交

mysql> show variables like 'autocommit';
#查看自动提交
mysql> set autocommit=0;
#临时关闭
[root@db01 world]# vim /etc/my.cnf
[mysqld]
autocommit=0
#永久关闭

事务演示

* 成功事务
mysql> create table stu(id int,name varchar(10),sex enum('f','m'),money
int);
mysql> begin;
mysql> insert into stu(id,name,sex,money) values(1,'zhang3','m',100),
(2,'zhang4','m',110);
mysql> commit;
* 事务回滚
mysql> begin;
mysql> update stu set name='zhang3';
mysql> delete from stu;
mysql> rollback;

事务日志redo

在mysql中,如果修改了数据,那么事务提交前,首先会被记录成redo日志写入磁盘,等到事务提交

时,再把新数据写入磁盘

这也就是经常说的WAL(Write-Ahead Log)。

redo,顾名思义“重做日志”,是事务日志的一种。

在事务ACID过程中,实现的是“D”持久化的作用。

特性:WAL(Write Ahead Log)日志优先写

REDO:记录的是,内存数据页的变化过程

REDO工作过程

update t1 set num=2 where num=1;
# 执行步骤
* 首先将t1表中num=1的行所在数据页加载到内存中buffer page
* MySQL实例在内存中将num=1的数据页改成num=2
* num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中
commit;
# 提交事务执行步骤
* 当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log
* 当写入成功之后,commit返回ok

事务日志undo

undo,顾名思义“回滚日志”,是事务日志的一种。

在事务ACID过程中,实现的是“A”原子性的作用。当然C和I的特性也和undo有关

redo和undo的存储位置

[root@db01 data]# ll /application/mysql/data/
-rw-rw---- 1 mysql mysql 50331648 Aug 15 06:34 ib_logfile0
-rw-rw---- 1 mysql mysql 50331648 Mar 6 2021 ib_logfile1
# redo位置
[root@db01 data]# ll /application/mysql/data/
-rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata1
-rw-rw---- 1 mysql mysql 79691776 Aug 15 06:34 ibdata2
# undo位置

事务中的锁

“锁”顾名思义就是锁定的意思

在事务ACID特性过程中,“锁”和“隔离级别”一起来实现“I”隔离性的作用。

排他锁:保证在多事务操作时,数据的一致性。

共享锁:保证在多事务工作期间,数据查询时不会被阻塞。

多版本并发控制(MVCC)

只阻塞修改类操作,不阻塞查询类操作
乐观锁的机制(谁先提交谁为准)

锁的粒度

MyIsam:低并发锁(表级锁)
Innodb:高并发锁(行级锁)

事务的四种隔离级别

READ UNCOMMITTED(读未提交):
允许事务查看其他事务所进行的未提交更改
READ COMMITTED:
允许事务查看其他事务所进行的已提交更改
REPEATABLE READ:
确保每个事务的 SELECT 输出一致
InnoDB 的默认级别
SERIALIZABLE:
将一个事务的结果与其他事务完全隔离,可串行化
在mysql配置文件如/etc/my.cnf中修改:
[mysqld]
transaction_isolation=read-uncommit   #修改隔离级别为RU
transaction_isolation=read-committed  #修改隔离级别为RC