一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于事务名称 事务id的文章,本文对文章事务名称 事务id好好的分析和解答,希望你能喜欢,只有你喜欢的内容存在,只有你来光临,我们才能继续前行。
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制,为多个版本的数据实现并发控制的技术。其基本思想是为每一次事务生成一个新版本的数据,在读取数据时可以选择不同版本的数据即实现的事务结果的完整性读取。(基于Mysql的回滚机制为达到并发场景下的读操作不需要锁定)
实现原理:主要是依赖记录中的三个隐式字段、undo日志、ReadView
三个隐式字段:
DB_TRX_ID
6byte,最近修改(修改/插入) 事务ID :记录创建这条记录/最后一次修改该记录的事务ID
DB_ROLL_PTR
7byte, 回滚指针 ,指向这条记录的上一个版本(存储于rollback segment里)
DB_ROW_ID
6byte, 隐含的自增ID (隐藏主键),如果数据表没有主键并且没有唯一键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
下面看一下MVCC的整个的运作的流程
二、 现在来了一个事务1对该记录的name做出了修改,改为Tom
从上面,我们就可以看出,不同事务或者相同事务的对同一记录的修改,会导致该记录的undo log成为一条记录版本线性表,既链表,undo log的链首就是最新的旧记录,链尾就是最早的旧记录。
查询时会读出ReadView;[未提交的事务id]数组 + 最大事务id,并根据ReadView从undo log日志中最新记录依次往下找
本篇文章参考 https://www.jianshu.com/p/8845ddca3b23
B站还有个程序猿up讲的这个也很不错 https://www.bilibili.com/video/BV1Vk4y1k7KQ?from=search&seid=
MVCC(Mutil-Version Concurrency Control),就是多版本并发控制。这种并发控制的方法,主要应用在RC和RR隔离级别的事务当中,利用执行select操作时,访问记录版本链,使得不同事物的读写,写读可以并发执行,提高系统性能。
Innodb 有两个隐藏字段 trx_id(事务id)和roll_pointer(回滚指针)。
transaction id :
innoDB里面每个事务有一个唯一的事务ID,叫作transaction id,它是在事务开始的时候向InnoDB的事务系统申请的,是按申请顺序严格递增的。
roll_pointer :
指向上一事务版本的指针。
版本链 :
是一个单链表结构,对于同一行数据,每一个事务对其进行更新的时候都会产生一个新的版本,就会存储在这个链表当中。
一个存储事务id的列表。
readview的几个参数:
m_ids:表示活跃事务id列表
min_trx_id:活跃事务中的最小事务id
max_trx_id:已创建的最大事务id
creator_trx_id:当前的事务id。
readview的生成时机:
RC隔离级别:每次读取数据前,都生成一个readview;
RR隔离级别:在第一次读取数据前,生成一个readview;
使用场景:
[ 创建事务节点 ] 当我创建一个新的事务需要读取一行数据, 我会查询活跃的事务列表; 假设我当前的事务id是200, 当前活跃的事务id没有我的200, 因此需要去拷贝一个最新的不活跃事务并在版本链最后插入一个新节点200; mysql会去对比版本链和readView, 假设版本链数据为[1,50,100,150], 活跃列表为[100,150], 说明100和150都是未提交的活跃事务, 再向前一个节点50不在活跃事务列表说明事务50已经提交, 所以事务200拷贝事务50并插入版本链最后, 且将200追加到readView活跃列表的最后一个元素
[ 使用事务节点 ] 当我再次进行200号事务的查询或修改, 我需要读版本链的数据, 因为上一次操作已经在版本链做了200号节点, 因此我读的数据都是200号节点的数据, 这样就隔离了其他未提交的事务; 我的全部增删查改都在200号版本链上进行
[ readView实现事务隔离级别 ]以上两点都是基于隔离级别"读已提交"来进行说明的; 当mysql设置为"可重复读"时, 不同事务仍然是保存在版本链的不同节点上, 只不过新的事务创建的时候拷贝了当下的readView列表, 只要新事物不提交就一直使用这个拷贝的活跃列表; 假设此时100号数据提交了, 我在新事务执行了select 会去查活跃列表发现100号事务还是未提交状态, 因此读取到的还是50号事务提交的记录。
原子性,一致性,隔离性,持久性。
未提交读(read uncommitted)、提交读(read committed)、可重复读(repeatable read)、序列化读(serializable)
今天我们来看看多个事务对缓存页里的同一条数据同时进行更新或者查询,此时会产生哪些问题?这里实际会涉及到 脏写、脏读、不可重复读、幻读, 四中问题。
这个脏写的话,它的意思是说有两个事务,事务A和事务B同时在更新一条数据,事务A先把它更新为A值,事务B紧接着就把它更新为B值。事务A是先更新的,它在更新之前,这行数据的值为NULL,所以此时事务A的undo log日志大概是这样的:更新之前这行数据的值为NULL,主键为XX 。
那么此时事务B更新完了数据的值为B,结果此时事务A突然回滚了,那么就会用它的undo log日志去回滚。此时事务A一回滚,直接就会把那行数据的值更新回之前的NULL值。所以对于事务B看到的场景,就是自己明明更新了,结果值却没了,这就是 脏写。
假设事务A更新了一行数据的值为A,此时事务B去查询了一些这行数据的值,看到的值是A,然后事务B拿着刚查询到的A值去处理各种业务。但是此时不幸的事情发生了,事务A突然回滚了,导致它刚才更新的A值没了,此时那行数据的值回滚为NULL值。这就是所谓的 脏读。 它的本质是事务B去查询了事务A修改过的数据,但是此时事务A还没有提交,事务A随时会回滚导致事务B查询了一个不存在的值。
接着我们来看一下 的问题,假设我们有一个事务A开启了,在这个事务A里会多次对一条数据进行查询。然后另外有两个事务,一个是事务B,一个是事务C,它们都是对一条数据进行更新的。假设缓存页里一条数据原来的值是A值,此时事务A开启之后,第一次查询这条数据,读取到的是A值。接着事务B更新了那行数据的值为B,同时提交事务,然后事务A第二次查询该行数据,此时查到的是事务B修改过的值B 。接着事务C更新了那行数据的值为C,同时提交事务,然后事务A第三次查询该行数据,此时查到的是事务C修改过的值C值。
那么上面的场景有什么问题呢?其实要说没问题也是可以的,毕竟事务B和C都提交事务了。但是要说有问题也是可以的,就是事务A可能第一次查询到的是A值,那么它可能希望的是在事务执行期间,如果多次查询数据,都是同样的一个A值。但是该场景下,A值明显不是可重复读的。
这种情况算不算一个问题呢?其实这是根据你的业务决定的。有的业务要的是可重复读,而有的业务却需要不可重复读。
假设一个事务A先发送一条SQL语句,里面有一个条件,要查询一批数据出来,比如“select * from table where id > 10”,类似这种SQL,它一开始查询出了10条数据。然后事务B往表里插入了几条数据,而且事务B还提交了。此时事务A再次查询,由于事务B插入了几条数据,导致这次它查询出来了12条数据。同样的SQL语句,两次的查询结果却不一样,所以开始怀疑自己是不是出现了幻觉?导致刚才幻读了?这就是幻读一词的由来。
在SQL标准中规定了4种事务隔离级别,就是说多个事务并发运行的时候,互相是如何隔离的,从而避免一些事务并发问题。这4种级别包括了: read uncommitted(读未提交)、read committed(读已提交)、repeatable read(可重复读)、serializable(串行化) 。
第一个read uncommitted隔离级别是不允许发生脏写的。也就是说,不可能两个事务在没提交的情况下去更新同一行数据的值,但是在这种隔离级别下,可能发生脏读、不可重复读、幻读。所以一般来说,是没有人做系统开发的时候把事务隔离级别设置为读未提交这个级别的。
第二个是read committed隔离级别,也就是俗称的RC级别,这个级别不会发生脏写和脏读。也就是说,别的事务没提交的情况下修改的值,你是绝对读不到的。但是,可能会发生不可重复读和幻读问题。
第三个是repeatable read隔离级别,也就是俗称的RR级别,就是可重复读级别。这个级别下,不会发生脏写、脏读、不可重复读的问题。事务一旦开启,多次查询一个值,会一直读到同一个值。但是它会发生幻读的问题。
最后一个隔离级别,就是serializable级别,这种级别,根本不允许多个事务并发执行,只能串行执行,所以不可能有幻读问题。但是这种级别一般除非脑子坏了,否则不可能设置这种级别。
MySQL默认设置的事务隔离级别都是RR级别的,而且MySQL的RR级别是可以避免幻读发生的。
下面的命令可以修改MySQL的默认事务隔离级别:
@Transaction(isolation=Isolation.DEFAULT),默认的就是DEFAULT值,这个就是MySQL默认支持什么隔离就是什么隔离级别。但是你可以手动改成其它的隔离级别,比如,isolation = Isolation.READ_COMMITTED级别,此时你就可以读取到其它事务已提交的数据。
简单来说,我们每条数据其实都有两个隐藏字段,一个是trx_id,一个是roll_pointer,这个trx_id就是最近一次更新这条数据的事务id,roll_pointer就是指向了你更新这个事务之前生成的undo log,关于undo log之前都讲过了。
以上内容是小编精心整理的关于事务名称 事务id的精彩内容,好的文章需要你的分享,喜欢事务名称 事务id这篇精彩文章的,请您经常光顾吧!
上一篇:仔仔的网名 仔的昵称
下一篇:更多运程
本文标题:事务名称 事务id
本文链接:http://m.shengxiao88.com/article/197770.html
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于事务名称 事务id的文章,本文对...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于仔仔的网名 仔的昵称的文章,本...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于zalo昵称取什么好 zalo昵称不...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于毛肚的个性名称 毛肚好听的名...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于面部昵称图解 面部好听的名字...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于拥军的网名 关于拥军的唯美名...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于好听的微信四字昵称女 好听的...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于带梅字的微信昵称4字女 带梅字...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于浅墨的昵称是什么意思呀 浅墨...
一篇好的文章需要好好的打磨,你现在浏览的文章是一篇关于想取个网络红人新昵称怎么取 ...