MySQL事务

目录

ACID

脏读、不可重复读、可重复读、幻读

MVCC机制


ACID

原子性(Actomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。

一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。

隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。

持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

 

脏读、不可重复读、可重复读、幻读

脏读(读未提交):事务A正对某条数据做修改,并且未提交事务;这时,事务B来读取该条数据,并且读到了事务A修改的数据。

不可重复读(读已提交):事务A第一次查询数据的值是1,一会事务B修改了该数据值为2,并且提交了事务,此时事务A再次查询到的数据值是2,读了人家事务提交的数据。

可重复读:事务A在执行过程中,对某个数据的值,无论读多少次都是值1;哪怕这个过程中事务B修改了数据的值还提交了,但是事务A读到的还是自己事务开始时这个数据的值。

幻读:幻读针对的是插入。例如事务A第一次查询到的是一条数据,一会事务B插入一条数据且满足事务A的查询条件,此时事务A再次查询就会查到2条数据。

串行化:解决幻读,就需要使用串行化级别的隔离级别,所有事务都串行起来,不允许多个事务并行操作。例如事务A只查询数据,那么B事务这个时候如果要update相同数据,则必须等待A事务完成。

MySQL的默认隔离级别是Read Repeatable,就是可重复读,就是说每个事务都会开启一个自己要操作的某个数据的快照,事务期间,读到的都是这个数据的快照罢了,对一个数据的多次读都是一样的。

 

MVCC机制

innodb存储引擎,会在每行数据的最后加两个隐藏列,一个保存行的创建时间,一个保存行的删除时间,但是这儿存放的不是时间,而是事务id,事务id是mysql自己维护的自增的,全局唯一。

事务id,在mysql内部是全局唯一递增的,事务id=1,事务id=2,事务id=3

idname创建事务id删除事务id
1张三1012
2李四9
2李四212

 

事务id=11的事务,查询id=1的这一行的时候,一定会找到创建事务id <= 当前事务id的那一行,select * from table where id=1,就可以查到上面那一行;

事务id=12的事务,将id=1的这一行给删除了,此时就会将id=1的行的删除事务id设置成12;

事务id=11的事务,再次查询id=1的那一行,能查到吗?能查到,要求创建事务id <= 当前事务id,当前事务id < 删除事务id;

事务id=11的事务,查询id=2的那一行,查到name=李四;

事务id=12的事务,将id=2的那一行的name修改成name=李四2;

事务id=11的事务,查询id=2的那一行,答案是:李四,创建事务id <= 当前事务id,当    前事务id < 删除事务id;

在一个事务内查询的时候,mysql只会查询创建时间的事务id小于等于当前事务id的行,这样可以确保这个行是在当前事务中创建,或者是之前创建的;同时一个行的删除时间的事务id要么没有定义(就是没删除),要么是必当前事务id大(在事务开启之后才被删除);满足这两个条件的数据都会被查出来。

那么如果某个事务执行期间,别的事务更新了一条数据呢?这个很关键的一个实现,其实就是在innodb中,是插入了一行记录,然后将新插入的记录的创建时间设置为新的事务的id,同时将这条记录之前的那个版本的删除时间设置为新的事务的id。

这样的话,这个事务其实对某行记录的查询,始终都是查找的之前的那个快照,因为之前的那个快照的创建时间小于等于自己事务id,然后删除时间的事务id比自己事务id大,所以这个事务运行期间,会一直读取到这条数据的同一个版本。

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值