jquery下拉列表的英文字母mysql数据库可重复读、幻读
事务基本特性ACID分别是:
原⼦性(Atomicity)
之下eclipse指的是⼀个事务中的操作要么全部成功,要么全部失败。
⼀致性(Consistency)
指的是数据库总是从⼀个⼀致性的状态转换到另外⼀个⼀致性的状态。⽐如A转账给B100块钱,假设中间sql执⾏过程中系统崩溃A也不会损失100块,因为事务没有提交,修改也就不会保存到数据库。
隔离性(Isolation)
指的是⼀个事务的修改在最终提交前,对其他事务是不可见的。
持久性(Durability)
指的是⼀旦事务提交,所做的修改就会永久保存到数据库中。
ACID靠什么保证的呢
mysql怎么读英语A原⼦性由undo log⽇志保证,它记录了需要回滚的⽇志信息,事务回滚时撤销已经执⾏成功的sql;
C⼀致性⼀般由代码层⾯来保证;(如tcc两阶段提交,事务回滚)
I隔离性由MVCC来保证;(多版本并发控制,保存当前时间快照)
D持久性由内存+redo log来保证,mysql修改数据同时在内存和redo log记录这次操作,事务提交的时候通过redo log刷盘,宕机的时候可以从redo log恢复;
⽽隔离性有4个隔离级别,分别是:
1、read uncommit 读未提交,可能会读到其他事务未提交的数据,也叫做脏读。
⽤户本来应该读取到id=1的⽤户age应该是10,结果读取到了其他事务还没有提交的事务,结果读取结果age=20,这就是脏读。
2、read commit 读已提交,两次读取结果不⼀致,叫做不可重复读。
不可重复读解决了脏读的问题,他只会读取已经提交的事务。
⽤户开启事务读取id=1⽤户,查询到age=10,再次读取发现结果=20,在同⼀个事务⾥同⼀个查询读
取到不同的结果叫做不可重复读。
3、repeatable read 可重复复读,这是mysql的默认级别,就是每次读取结果都⼀样,但是有可能产⽣幻读。
4、serializable 串⾏,⼀般是不会使⽤的,他会给每⼀⾏读取的数据加锁,会导致⼤量超时和锁竞争的问题。
多版本并发控制MVCC
- MVCC是⾏级锁的⼀个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但⼤都实现了⾮阻塞的读操作,写操作也只锁定必要的⾏。
- MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执⾏多长时间,每个事务看到的数据都是⼀致的。根据事务开始的时间不同,每个事务对同张表,同⼀时刻看到的数据可能是不⼀样的。
- InnoDB的MVCC,是通过在每⾏记录后⾯保存两个隐藏的列来实现的。这两个列,⼀个保存了⾏的创建时间,⼀个保存⾏的过期时间(或删除时间)。当然存储的并不是实际的时间值,⽽是系统版本号。每开始⼀个新的事务,系统版本号都会⾃动递增。事务开始时刻的系统版本号会作为事务的版本号,
⽤来和查询到的每⾏记录的版本号进⾏⽐较。
- MVCC只在可重复读和读提交的隔离级别⽣效。其它两个级别都不兼容
事务到底是隔离的还是不隔离的
innodb⽀持RC(读提交)和RR(可重复读)隔离级别实现是⽤的⼀致性视图(consistent read view)
事务在启动时会拍⼀个快照,这个快照是基于整个库的。基于整个库的意思就是说⼀个事务内,整个库的修改对于该事务都是不可见的(对于快
照读的情况)。如果在事务内select t表,另外的事务执⾏了DDL t表,根据发⽣时间,要吗锁住要嘛报错
事务是如何实现的MVCC呢?
每个事务都有⼀个事务ID,叫做transaction id(严格递增)
事务在启动时,到已提交的最⼤事务ID记为up_limit_id。
事务在更新⼀条语句时,⽐如id=1改为了id=2.会把id=1和该⾏之前的row trx_id写到undo log⾥。并且在
数据页上把id的值改为2,并且把修改这条语句的transaction id记在该⾏⾏头。
再定⼀个规矩,⼀个事务要查看⼀条数据时,必须先⽤该事务的up_limit_id与该⾏的transaction id做⽐对
如果up_limit_id>=transaction id,那么可以看.如果up_limit_id<transaction id,则只能去undo log⾥去取。去undo log查数据的时候,也需要做⽐对,必须up_limit_id>transaction id,才返回数据
什么是当前读,
由于当前读都是先读后写,只能读当前的值,所以认为当前读.会更新事务内的up_limit_id为该事务的transaction id
为什么RR能实现可重复读⽽RC不能,分两种情况
快照读的情况下,rr(可重复读)不能更新事务内的up_limit_id,⽽rc(读提交)每次会把up_limit_id更新为快照读之前最新已提交事务的transaction id,则rc(读提交)不能可重复读
当前读的情况下,rr(可重复读)是利⽤record lock+gap lock来实现的,⽽rc(读提交)没有gap,所以rc不能可重复读
幻读是什么,幻读有什么问题
幻读指的是⼀个事务在前后两次查询同⼀个范围的时候,后⼀次查询看到了前⼀次查询没有看到的⾏。(如假设张三开启了事务,select了两次,第⼆次查出来的数据⽐第⼀次的多了,如同出现了幻觉⼀样)
在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插⼊的数据的。因此,幻读在“当前读”下才会出现。
innodb的默认事务隔离级别是rr(可重复读)。它的实现技术是mvcc。基于版本的控制协议。该技术不仅可以保证innodb的可重复读,⽽且可以防⽌幻读。但是它防⽌的是快照读,也就是读取的数据虽然是⼀致的,但是数据是历史数据。如何做到保证数据是⼀致的(也就是⼀个事务,其内部读取对应某⼀个数据的时候,数据都是⼀样的),同时读取的数据是最新的数据。innodb提供了⼀个间隙锁的技术。也就是结合grap锁与⾏锁,达到最终⽬的。当使⽤索引进⾏插⼊的时候,innodb会将当前的节点和上⼀个节点加锁。这样当进⾏select的时候,就不允许加x锁。那么在进⾏该事务的时候,读取的就是最新的数据。
实现:java程序打包成exe
1. 快照读(snapshot read)
gzip压缩命令成gz格式简单的select操作,其他的都属于当前读。
实现为mvcc,⽣成快照数据,实现可重复读,不会出现幻读。
2.当前读(current read)
select ... lock in share mode
select ... for update
insert
matlab怎么画三维图update
delete
在RR级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。
所以从上⾯的显⽰来看,如果需要实时显⽰数据,还是需要通过加锁来实现。这个时候会使⽤next-key技术来实现。
总结:在mysql中,提供了两种事务隔离技术,第⼀个是mvcc,第⼆个是next-key技术。这个在使⽤不同的语句的时候可以动态选择。不加lock inshare mode之类的就使⽤mvcc。否则使⽤next-key。mvcc的优势是不加锁,并发性⾼。缺点是不是实时数据。next-key的优势是获取实时数据,但是需要加锁。同时需要注意⼏点:1.事务的快照时间点是以第⼀个select来确认的。所以即便事务先开始。但是select在后⾯的事务的update之类的语句后进⾏,那么它是可以获取后⾯的事务的对应的数据。2.mysql中数据的存放还是会通过版本记录⼀系列的历史数据,这样,可以根据版本查数据。
next key lock
Next-Key锁是索引记录上的记录锁和索引记录之前间隙上的间隙锁的组合。
假设⼀个索引包含值10、11、13和20。此索引可能的next-key锁包括以下区间:(-∞, 10],(10, 11],(11, 13],(13, 20],(20, ∞ ]
对于最后⼀个间隙,∞不是⼀个真正的索引记录,因此,实际上,这个next-key锁只锁定最⼤索引值之后的间隙。所以,Next-Key 的锁的范围都是左开右闭的。Next-Key Lock和Gap Lock⼀样,只有在InnoDB的RR隔离级别中才会⽣效。
Repeatable Reads能解决幻读
很多⼈看过⽹上的关于数据库事务级别的介绍,会认为MySQL中Repeatable Reads能解决不可重复读的问题,但是不能解决幻读,只有Serializable才能解决。但其实,这种想法是不对的。
因为MySQL跟标准RR不⼀样,标准的Repeatable Reads确实存在幻读问题,但InnoDB中的Repeatable Reads是通过next-key lock解决了RR的幻读问题的。因为我们知道,因为有了next-key lock,所以在需要加⾏锁的时候,会同时在索引的间隙中加锁,这就使得其他事务⽆法在这些间隙中插⼊记录,这就解决了幻读的问题。
MySQL的加锁原则
Record Lock、Gap Lock和Next-Key Lock,但是并没有说明加锁规则。关于加锁规则,看了丁奇⼤佬的《MySQL实战45讲》中的⽂章之后理解的,他总结的加锁规则⾥⾯,包含了两个“原则”、两个“优化”和⼀个“bug”:
原则 1:加锁的基本单位是 next-key lock。是⼀个前开后闭区间。原则 2:查过程中访问到的对象才会加锁。优化 1:索引上的等值查询,给唯⼀索引加锁的时候,next-key lock 退化为⾏锁。优化 2:索引上的等值查询,向右遍历时且最后⼀个值不满⾜等值条件的时候,next-key lock 退化为间隙锁。⼀个 bug:唯⼀索引上的范围查询会访问到不满⾜条件的第⼀个值为⽌。
rr级别下当前读加锁问题,能否解决幻读问题参考更多其他⽂章。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论