命令记不住

登陆

Mysql 事务

Mysql事务

1.事务简介

OLTP,在线事务处理系统
事务:主要是针对DML(insert、update、delete)来进行控制的。

  • 一组数据操作执行步骤,这些步骤被视为一个工作单元
  • 用于对多个语句进行分组
  • 可以在多个客户机并发访问同一个表中的数据时使用
  • 所有步骤都成功或都失败
  • 如果所有步骤正常,则执行
  • 如果步骤出现错误或不完整,则取消

1.1事务的ACID特性

1.Atomic(原子性)

所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态。

2.Consistent(一致性)

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

3.Isolated(隔离性)

事务之间不相互影响

4.Durable(持久性)

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

1.2事务的完整生命周期

事务:比较完美的生命周期

begin	----->开始一个事务
DML1
DML2
DML3
commit	----->正常提交(完成)一个事务

事务:

begin
DML1 
DML2 
rollback

事务:非自然

begin
DML1
DML2 
由于某些原因(断电了等原因)

1.3事务控制语句

begin     ---->开始一个事务
commit    ---->提交一个事务
rollback  ---->回滚一个事务
set autocommit=1/0;   

注:
自动提交是否打开,一般在有事务需求的MySQL中,将其关闭
不管有没有事务需求,我们一般也都建议设置为0,可以很大程度上提高数据库性能
数据库修改:

set autocommit=0;  
set global autocommit=0;

配置文件

vim /etc/my.cnf
autocommit=0     

1.4隐式提交语句
用于隐式提交的 SQL 语句:

START TRANSACTION
SET AUTOCOMMIT = 1 

导致提交的非事务语句:

DDL语句:	(ALTER、CREATE 和 DROP)
DCL语句:	(GRANT、REVOKE 和 SET PASSWORD)
锁定语句:(LOCK TABLES 和 UNLOCK TABLES)

导致隐式提交的语句示例:

TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE

1.5开始事务流程:

1、检查autocommit是否为关闭状态
select @@autocommit;
或者:
show variables like 'autocommit';
2、开启事务,并结束事务
[begin]
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
rollback;


[begin]
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
commit;

2.ACID怎么实现

2.1Redo是什么?

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

作用是什么?

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

redo:

redo的日志文件:iblogfile0 iblogfile1
redo的buffer:数据页的变化信息+数据页当时的LSN号

redo的刷新策略:

commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘

2.2undo 回滚日志
undo是什么?

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

作用是什么?

在事务ACID过程中,实现的是“A” 原子性的作用
另外CI也依赖于Undo

3.事务的ACID如何保证

**1 redo:**1.Redo是什么?

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

作用是什么?

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

redo:

redo的日志文件:iblogfile0 iblogfile1
redo的buffer:数据页的变化信息+数据页当时的LSN号

redo的刷新策略:

commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘

2.LSN: 日志序列号

存放位置:
redo 日志文件(重做日志,前滚日志):ib_logfile0 ~ 1
数据文件中: t1.ibd
日志缓冲区:log buffer
数据缓冲区:data buffer

MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致,
        如果不一致就会触发CSR,最终保证一致

redo 日志文件是轮询使用

2.undo

2.1undo是什么?

undo,顾名思义“回滚日志”

作用是什么?

在事务ACID过程中,实现的是“A” 原子性的作用
另外CI也依赖于Undo

2.3概念性的东西:

redo怎么应用的
undo怎么应用的

CSR(自动故障恢复)过程
LSN :日志序列号 
TXID:事务ID
CKPT(Checkpoint):

3.锁

“锁”顾名思义就是锁定的意思。
“锁”的作用是什么?

在事务ACID过程中,“锁”和“隔离级别”一起来实现“I”隔离性和"C" 一致性 (redo也有参与).

悲观锁:行级锁定(行锁)

谁先操作某个数据行,就会持有<这行>的(X)锁.

乐观锁: 没有锁

4.隔离级别

影响到数据的读取
默认的级别是 RR模式.

4.1介绍:

RU(read uncommited) : 读未提交
事务没提交,其他事务也可以看到修改后的数据(脏页读)
RC : 读已提交
事务已提交,其他事务才可以可以看到修改后的数据(会出现幻读)

RR : 可重复读 
不管是事务执行前,事务执行中,事务结束后,同一个会话一定读到的是同一个数据,MySQL默认的隔离级别.
必须支持事务(undo快照),必须有索引,可以防止幻读,读一致性的目的.

S : 可串行化

4.2扩展

GAP 
next-lock

RR模式(对索引进行删除时):

GAP:          间隙锁
next-lock:    下一件锁定

id(有索引) 
1 2 3 4 5 6  

GAP:

在对3这个值做变更时,会产生两种锁,一种是本行的行级锁,另一种会在2和4索引键上进行枷锁
next-lock:
对第六行变更时,一种是本行的行级锁,在索引末尾键进行加锁,6以后的值在这时是不能被插入的。

总之:

GAP、next lock都是为了保证RR模式下,不会出现幻读,降低隔离级别或取消索引,这两种锁都不会产生。
推荐阅读