深入理解mysql的锁和mvcc

这篇具有很好参考价值的文章主要介绍了深入理解mysql的锁和mvcc。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基础

1 锁讲解:面试必备-行锁、表锁 - 乐观锁、悲观锁的区别和联系

2 mvcc机制讲解(如何实现各种隔离级别):数据库基础(四)Innodb MVCC实现原理

刚读完上面两篇内容,可能会有很多疑惑的地方,下面是我自己整理出来的一些疑惑点:

1 rr级别如何防止幻读

“RR” 是 “Repeatable Read”(可重复读)的缩写,它是数据库的四种标准隔离级别之一,其余三种是 “Read Uncommitted”(读未提交),“Read Committed”(读已提交)和 “Serializable”(串行化)。不同的隔离级别提供了不同的并发控制,可以在 “数据一致性” 和 “并发性能” 之间进行权衡。

可重复读(Repeatable Read,RR)隔离级别保证了在一个事务中多次读取同一数据的结果是一致的,也就是说,该级别的事务不会看到其他事务对该数据的修改。这可以防止 “不可重复读” 的问题,即一个事务在读取同一行数据的两个不同时间点上看到了不同的数据。

然而,即使在 RR 隔离级别下,也可能会出现 “幻读”(Phantom Read)问题。幻读是指在一个事务处理过程中,第一次和最后一次查询的结果不一致。这种现象并不是由于读取的记录的值被其他事务更改引起的,而是由于其他事务插入或删除了一些记录,导致我们看到了“幻影”记录。

防止幻读的最主要的方法是使用最高级别的隔离级别——串行化(Serializable)。在串行化级别下,事务是完全串行执行的,自然就不存在幻读问题。但是这种级别的隔离在并发性能上有很大的损失。

在实践中,有一些数据库系统(如 MySQL 的 InnoDB 存储引擎)会通过 “Next-Key Locking” 来在 RR 级别下防止幻读。Next-Key Locking 是一种锁定策略,它不仅锁定了查询所访问的索引记录,还锁定了索引中的一个“间隙”(Gap Locking),这样就可以防止其他事务在该“间隙”中插入新的记录,从而避免了幻读的产生。

注意:Next-Key Locking 策略可能导致锁冲突增多,可能降低并发性能。在实际应用中,需要根据实际情况权衡使用。

2 next-lock(临键锁)和gap-lock(间隙锁)

两者的区别

Next-Key Locking 和 Gap Locking 都是数据库管理系统(例如 MySQL 的 InnoDB 引擎)在可重复读(Repeatable Read,RR)隔离级别下防止幻读的技术。它们都涉及到了对数据的一种“范围锁定”,即不仅锁定实际访问到的记录,还锁定记录之间的“间隙”。两者的主要区别在于锁定的精细度。

  1. Next-Key Locking:Next-Key Locking 是 InnoDB 默认的行锁定方式,它是一种组合锁定,包括了行锁(record lock)和间隙锁(gap lock)。具体来说,如果一个事务 T1 访问了一个索引记录 R,那么 Next-Key Locking 会对 R 的“键值-间隙”和 R 本身进行锁定。这样,不仅阻止了其他事务修改 R,也阻止了其他事务在 R 的键值-间隙内插入新的记录。Next-Key Locking 可以有效地防止幻读。

  2. Gap Locking:Gap Locking 只锁定索引记录之间的间隙,而不锁定记录本身。例如,如果一个事务 T1 访问了索引记录 R1 和 R2,那么 Gap Locking 会锁定 R1 和 R2 之间的间隙,但并不锁定 R1 和 R2 本身。这意味着其他事务可以修改 R1 和 R2 的内容,但不能在 R1 和 R2 之间插入新的记录。Gap Locking 主要用于实现读取的一致性和防止幻读,但它不防止不可重复读。

Next-Key Locking 更加保守,它提供了更强的数据一致性保证,但可能会降低并发性能。而 Gap Locking 则更加宽松,它允许对已有记录的并发修改,但仍然可以防止幻读。在实际应用中,应根据具体需求选择合适的锁定策略。

利用临键锁可以完美解决幻读的问题,面试官问了一下真的是完美的吗?

总结:安全上完美,性能上有缺陷

"完美"可能是一个过于绝对的表述,因为即使使用了临键锁,也不能解决所有的并发问题,而且它会带来其他的开销。

临键锁是InnoDB在可重复读隔离级别下用于防止幻读的一种锁,它可以防止在某个范围内插入新的记录,这确实可以防止幻读的发生。然而,这并不能解决所有的并发问题。例如,临键锁不能防止"写偏斜"问题,即当两个事务都读取相同的数据并试图修改它们时可能发生的问题。

此外,临键锁会增加锁的开销,可能导致性能降低。临键锁需要锁定一定范围的记录,而不仅仅是单个记录,这可能会阻止其他并发的事务访问这个范围内的记录,即使这些事务并不直接与被锁定的记录冲突。

所以,虽然临键锁可以有效地解决幻读问题,但是否能称之为"完美",需要考虑到它对并发性和性能可能带来的影响。

可重复读是由行锁来保证的吗

可重复读(Repeatable Read,RR)的保证并不仅仅依赖于行锁。在实际的数据库系统中,RR 隔离级别通常需要结合使用多种技术来实现,包括行锁,间隙锁(Gap Lock),多版本并发控制(MVCC,Multi-Version Concurrency Control)等。

行锁可以防止同一行数据被其他事务并发修改,但行锁并不能防止“幻读”(Phantom Read)问题。幻读是指在一个事务内,两次查询的结果不一致,而这种不一致并不是由于查询的记录本身被修改,而是由于新的记录的插入或旧的记录的删除。

为了解决幻读问题,许多数据库系统会使用间隙锁(Gap Lock)。间隙锁可以锁定两个索引记录之间的“间隙”,阻止其他事务在这个间隙中插入新的记录。

而多版本并发控制(MVCC)则是另一种重要的技术,它可以允许多个读事务同时访问同一行数据,而不会互相阻塞。在 MVCC 中,每个写操作都会创建一个数据行的新版本,读操作则会访问到一个适当的旧版本。这样,每个事务都可以在一致的快照中运行,就像它是唯一在运行一样。

所以,可重复读隔离级别通常需要行锁、间隙锁、MVCC 等多种技术共同实现。

来自MVCC链接的一个问题

原文: MVCC通过保存数据的历史版本,根据比较数据的版本号来决定数据的是否显示,在不需要加读锁的情况就能达到事务的隔离效果,最终可以在读取数据的时候可以同时进行修改,修改数据时候可以同时读取,极大的提升了事务的并发性能。

问题:当写时数据进行读取,读取时进行修改,不会产生并发问题嘛?比如同时有两个请求打进来,一个读一个写,但是写先执行,读后执行,这个读操作到底是应该在当前版本的数据上进行操作呢还是在写操作结束后进行?

答: 你对多版本并发控制(MVCC,Multi-Version Concurrency Control)的理解是正确的。MVCC 通过保存数据的历史版本,并在读取数据时选择适当的版本,可以让读取操作和修改操作同时进行,从而提高事务的并发性能。

对于你提到的问题,“当写时数据进行读取,读取时进行修改,不会产生并发问题吗?”,实际上在 MVCC 模型中是有相应的规则和策略来处理这种情况的。

在 MVCC 中,每个事务在开始时都会获得一个唯一的事务ID(也被称为版本号)。当一个事务想要读取一个数据项时,它会看到的是版本号不大于它自己事务ID的最新版本。当一个事务想要修改一个数据项时,它会创建一个新的版本,其版本号是这个事务的事务ID。

因此,对于你的问题,假设有两个事务T1(写)和T2(读),其中T1的事务ID小于T2的事务ID。如果T1先执行,它会创建一个新的数据版本,版本号为T1的事务ID;然后当T2执行时,它会看到的是版本号不大于T2事务ID的最新版本,也就是T1创建的那个版本。

这样,即使读取操作和修改操作并发进行,也不会出现数据一致性问题,因为每个事务都是在一致的数据快照中运行的。在这种模式下,读操作不会阻塞写操作,写操作也不会阻塞读操作,从而实现了高并发性能。

但请注意,虽然 MVCC 可以提高并发性能,但它并不能解决所有的并发问题。例如,它不能解决两个事务同时修改同一数据项的问题。这种情况通常需要使用锁或其他并发控制机制来处理。

事务T1是对自己持有的版本数据做更改嘛?这种情况下,T2读取的到数据是不是有可能是更改过后的?

在MVCC(Multi-Version Concurrency Control)的机制中,事务在进行写操作(例如更新一个数据项)时,会创建该数据项的一个新版本(其实该新版本还是放在数据行中,原来的版本位于undo log行,参考mvcc链接2.4的demo),而不是直接修改原始数据。新版本的版本号等于该事务的事务ID。原始数据的版本会被保留,以便其他还在使用旧版本数据的事务能够继续访问。

假设有两个事务T1和T2,T1是一个写事务,T2是一个读事务,它们的事务ID分别是ID1和ID2,并且ID1 < ID2。当T1想要修改一个数据项时,它会创建一个新的数据版本,版本号为ID1。当T2想要读取这个数据项时,它会看到的是版本号不大于ID2的最新版本。因为ID1 < ID2,所以T2可以看到T1创建的新版本。

但是,具体T2能看到哪个版本的数据,也取决于T1和T2的开始时间以及MVCC的实现策略。例如,如果T2开始时T1还没有提交,那么T2可能只能看到T1修改之前的数据版本;如果T2开始时T1已经提交,那么T2可能就能看到T1修改后的数据版本。

需要注意的是,MVCC能确保的是事务的一致性视图,也就是在一个事务中,不管数据是否被其他事务修改,它看到的数据总是一致的。对于并发的读写操作,是否会有冲突,要看具体的并发控制策略和隔离级别。在某些情况下,可能需要使用锁或其他同步机制来防止并发冲突。

如何理解“MVCC能确保的是事务的一致性视图,也就是在一个事务中,不管数据是否被其他事务修改,它看到的数据总是一致的”

“MVCC能确保的是事务的一致性视图,也就是在一个事务中,不管数据是否被其他事务修改,它看到的数据总是一致的”,这句话的意思是:在多版本并发控制(MVCC)的机制下,每一个事务看到的都是一致的、不变的数据快照,这个快照取决于该事务开始的时间点。这就是所谓的"一致性视图"。

这是如何实现的呢?当事务开始时,它会获得一个唯一的事务ID,这个ID也代表了事务开始的时间点。当这个事务想要读取一个数据项时,它会看到的是版本号不大于它自己事务ID的最新版本。也就是说,这个事务只能看到它开始时存在的数据版本,不能看到在它开始之后其他事务创建的新版本。即使在该事务执行过程中,其他事务对数据进行了修改,这个事务看到的数据也不会改变。

例如,假设事务T1在时间点1开始,此时它读取到的数据项A的版本为1。在T1执行过程中,另一个事务T2在时间点2修改了数据项A,创建了版本2。然而,即使数据项A的实际版本已经变为2,T1仍然能看到的是版本1的数据,因为版本1是在T1开始时存在的版本。因此,无论数据如何变化,T1看到的数据总是一致的。

这种特性使得在MVCC机制下,读操作不需要阻塞写操作,写操作也不需要阻塞读操作,可以提高并发性能。同时,由于每个事务都在一致的数据快照中运行,所以也能保证事务的一致性。

在正常使用锁机制的情况下,写操作T1和读操作T2,如果T1先执行,那么T2就只能阻塞等待T1执行完毕后读取到更新后的数据呢?

在使用锁机制的情况下,如果一个事务(T1)获取了对某个数据项的写锁,那么其他所有试图读取或者写入这个数据项的事务(比如 T2)都会被阻塞,直到 T1 释放了这个锁。所以,在这种情况下,T2 的确会等待 T1 执行完毕并释放锁之后,才能读取到更新后的数据。

这种阻塞等待的情况可能会导致并发性能下降,特别是在高并发的系统中。为了解决这个问题,一种方法是使用非阻塞的并发控制机制,比如 MVCC(Multi-Version Concurrency Control)。在 MVCC 中,读操作不会阻塞写操作,写操作也不会阻塞读操作,因此可以提高并发性能。

然而,虽然 MVCC 可以提高并发性能,但它也有一些限制和开销,比如需要维护多个版本的数据,需要处理版本冲突等问题。因此,在实际应用中,应该根据具体的需求和环境,选择合适的并发控制策略。

如果写操作T1中间执行完事务,但是T2在T1结束后又读取了一次该数据,此时读取的是提交后的数据嘛还是提交前的呢?

在多版本并发控制(MVCC)的模型中,事务开始时获取一个事务ID,该ID同时也是一个时间戳,代表了事务开始的时间点。这个事务对数据的所有读取操作,都只会看到其开始时间(即事务ID)之前的数据版本。

如果写事务T1在执行过程中提交了,那么它对数据的修改将会生成一个新的数据版本。这个新的版本的版本号将会等于T1的事务ID。

对于读事务T2来说,如果它在T1提交之前就已经开始了,那么即使T1提交了新的数据版本,T2依然只能看到它开始时那一刻的数据版本,也就是说,它看到的仍然是T1提交前的数据。

但是,如果T2是在T1提交之后才开始的,那么T2在读取数据时,会看到T1提交的新版本数据,因为这个版本的数据是在T2开始之前就已经存在的。

所以,T2读取的是提交后的数据还是提交前的数据,取决于T2的开始时间是在T1提交之前还是之后。这就是MVCC模型能够提供一致性视图的原理。

关于read view的问题

材料:

2.5 Read view 匹配条件:

1、数据事务ID <up_limit_id 则显示

如果数据事务ID小于read view中的最小活跃事务ID,则可以肯定该数据是在当前事务启之前就已经存在了的,所以可以显示。

2、数据事务ID>=low_limit_id 则不显示

如果数据事务ID大于read view 中的当前系统的最大事务ID,则说明该数据是在当前read view
创建之后才产生的,所以数据不予显示。

3、up_limit_id <=数据事务ID<low_limit_id 则与活跃事务集合trx_ids里匹配

如果数据的事务ID大于最小的活跃事务ID,同时又小于等于系统最大的事务ID,这种情况就说明这个数据有可能是在当前事务开始的时候还没有提交的。

所以这时候我们需要把数据的事务ID与当前read view 中的活跃事务集合trx_ids 匹配:

情况1: 如果事务ID不存在于trx_ids 集合(则说明read view产生的时候事务已经commit了),这种情况数据则可以显示。

情况2: 如果事务ID存在trx_ids则说明read
view产生的时候数据还没有提交,但是如果数据的事务ID等于creator_trx_id
,那么说明这个数据就是当前事务自己生成的,自己生成的数据自己当然能看见,所以这种情况下此数据也是可以显示的。

情况3: 如果事务ID既存在trx_ids而且又不等于creator_trx_id那就说明read
view产生的时候数据还没有提交,又不是自己生成的,所以这种情况下此数据不能显示。

4、不满足read view条件时候,从undo log里面获取数据

当数据的事务ID不满足read view条件时候,从undo log里面获取数据的历史版本,然后数据历史版本事务号回头再来和read
view 条件匹配 ,直到找到一条满足条件的历史数据,或者找不到则返回空结果;

如何理解这里的“数据事务ID”,是指当前的读事务id嘛,为什么事务号不是最大的呢,事务id不应该是自增的嘛?

在MySQL的InnoDB引擎中,事务采用了多版本并发控制(MVCC)机制。在这个机制下,每个数据行都有一个关联的事务ID,代表了这个数据行版本的创建者。当一个事务修改数据行时,它会创建一个新版本的数据行,而新版本的事务ID就是该事务的ID。因此,"数据事务ID"指的是创建这个数据行版本的事务ID。

对于你的第一个问题,"数据事务ID"并不是当前读事务的ID,而是创建当前版本数据行的事务的ID。InnoDB引擎确实使用了一个自增的事务ID来标识事务,但是你需要理解的是,每个事务在它开始时获取的ID,是在那个时间点的最大值,后来开始的事务获取的ID将会更大。所以,如果一个数据行的事务ID(即创建它的事务的ID)小于read view中的最小活跃事务ID,那么我们可以确定,这个数据行是在当前事务开始之前就已经创建了的,因此可以被当前事务看到。

这里的“该数据”是指表中正在存储的当前最新版本的记录嘛?

对于你的第二个问题,"该数据"是指当前读事务试图访问的数据行的某个版本。这个版本可能并不是数据行的当前最新版本,因为在MVCC中,读事务可能会看到旧版本的数据行,具体取决于读事务的开始时间和read view的内容。这就是MVCC能够提供一致性视图的方式。

在下面这种情况下,可能数据事务ID是一个提前执行完的写操作,对不对

数据事务ID>=low_limit_id 则不显示

如果数据事务ID大于read view 中的当前系统的最大事务ID,则说明该数据是在当前read view
创建之后才产生的,所以数据不予显示。

在你提到的这种情况下,"数据事务ID"可能确实是由一个已经提交的写事务创建的。如果数据行的事务ID大于read view的low_limit_id,说明这个数据行的版本是在当前读事务开始后才被创建的。因此,即使这个写事务已经提交,这个数据版本仍然不会被当前的读事务看到,因为在MVCC中,每个事务只能看到它开始时刻及之前的数据版本。

这时read view中的活跃事务链表都是读事务嘛,有没有写事务呢?

Read view中记录的活跃事务列表包括了在该读事务开始时刻,所有还没有提交的事务,不论这些事务是读事务还是写事务。如果是写事务,那么它可能在之后修改数据,创建新的数据版本,但这些新版本的数据不会被当前的读事务看到。如果是读事务,那么它不会修改数据,但是为了防止出现幻读(phantom read)问题,需要将其包含在活跃事务列表中

为什么将读事务放入read view活跃事务链表中就能防止幻读问题呢?

幻读是一种并发控制问题,当一个事务在读取一些行,然后另一个事务插入了一些新的行,再回头读取时,原事务发现有新的“幻影”行出现。如果将读事务放入read view的活跃事务链表中,那么其他并发的读事务就无法看到该写事务未提交的变更,因此在一致性视图中它不会看到新的“幻影”行,从而防止了幻读问题。这是因为mvcc的规范决定的:一个事务只能看到版本号比当前事务id小于等于的版本数据

为什么更新行的事务id还可以存在于活跃事务链表中,既然都更新了行,不应该代表已经提交了吗?

首先这里的"更新了行"只是指将旧版本的数据挪到了undo log日志中,并且新版本的数据就占据了当前的数据行,似乎是更新了,但是还没有提交,所以read view时本身也可能在活跃事务链表中。

MVCC的缺点相关

什么是write skew?

写偏是一个更复杂的现象(并发写的问题),它涉及到两个或多个事务同时读取相同的数据,然后基于读取的数据修改它们。这可能导致数据库处于不一致的状态。例如,两个事务都读取了同一个数据,然后都基于读取的数据进行了修改,可能会导致一些冲突和数据的不一致。要解决写偏,可能需要采取更高级的并发控制机制,例如使用乐观锁(Optimistic Locking)或悲观锁(Pessimistic Locking)

举个例子:
如果有两个座位,且两个用户(事务A和事务B)各自预定一个座位,那么座位数应该会变为0,当A和B同时读取剩余座位数(2个),然后都决定订一个座位,每个人都认为预订后应剩下一个座位。但是当两个事务都提交的时候,由于他们都是从2开始减去了一个座位,结果会是1个座位,而不是0。这就是所谓的write skew问题。

Read Skew 呢?

Read Skew(读偏斜): 在同一个事务中,多次读取同一数据项返回的结果不同。也就是上面Read-Write Skew中提到的“不可重复读”问题。

MVCC有什么缺陷?

mvcc并不能解决多个写事务的并发问题(不能解决write skew问题),只能用于解决读-写事务之间的并发问题。

为什么mvcc并不能解决多个读写复合事务之间或者写和写事务之间的并发问题

事务的类别

只读、只写、读写复合事务,一般mvcc只能解决只读和只写事务,或者只读和只读事务之间的并发问题,但是解决不了复合事务间或者只写和只写事务之间的并发问题

对于同时包含读和写操作的事务,MVCC同样能够很好的处理读操作。但是,对于写操作,如果写操作依赖于事务中的读操作,那么就可能出现问题。这就是所谓的"读-写偏斜"(read-write skew)

如何解决mvcc的write-skew问题或者写-写的事务问题?

1 让事务串行化执行(串行化隔离级别),但是并发度很低
2 数据库中使用带版本号的乐观锁,这样每次都只会有一个事务执行成功
3 可以使用分布式锁,让每次只放行一个事务去数据库中修改这个数据行或者相关业务
4 悲观锁:悲观锁假设并发事务会导致数据不一致,因此在修改数据前先上锁,防止其他事务并发修改。在我们的银行账户例子中,可以在检查余额和修改余额之间对账户进行加锁。这样,只有当一个事务完成后,另一个事务才能继续,从而避免了write skew问题。但是,悲观锁可能导致并发性能下降。

MVCC的应用场景

mvcc和其他的锁一样都只能保证事务的隔离性,并不能保证业务上存在依赖的事务的安全对吗?

是的,MVCC只能保证事务的隔离性,即并发执行的事务不会互相干扰。但是,它不能保证业务上存在的依赖关系。这需要在业务逻辑层面进行处理。例如,在秒杀场景中,即使使用了MVCC,也可能需要使用乐观锁或悲观锁等技术来保证商品不会超卖。

快照读和当前读,在秒杀场景中,应用哪个

在秒杀场景中,我们通常需要保证库存的正确性,因此需要实时地知道当前的库存状态,也就是我们需要"当前读"。快照读虽然能提供较高的并发性能,但是由于它是基于某个时间点的数据快照,可能无法反映出实时的库存状态,因此可能不适合秒杀这种对实时性要求较高的场景。

快照读取的可能是旧数据,存在安全问题吗?

快照读取的数据可能是旧的,这在一些场景下可能会带来问题。以秒杀为例,如果我们基于快照读取的库存数据来进行下单操作,那么可能会出现超卖的情况。比如说,商品的实际库存只有1,但是在多个事务的快照读中,它们都看到库存为1,于是都进行了下单操作,结果导致实际卖出了多件商品,这就是一种安全问题。

但是,这并不是说快照读没有用处。在一些对数据实时性要求不那么高,但对并发性能有较高要求的场景下,快照读可以提供较好的性能。例如,我们要统计用户的购买历史,在这种情况下,数据的实时性就不那么重要,而快照读可以提供更好的并发性能。

关于使用快照读还是当前读,mysql数据库可以设置的吗,粒度精确到表呢还是库呢

在MySQL中,你可以在每个事务的基础上选择使用快照读(也称为一致性读)或者当前读。这是通过设置事务的隔离级别来实现的。例如,如果你选择"READ COMMITTED"隔离级别,那么每次查询都会读取最新的数据(当前读)。而如果选择"REPEATABLE READ"隔离级别,那么在事务开始时就会创建一个数据快照,之后的所有查询都会基于这个快照来读取数据(快照读)。这个设置是针对每个事务的,不能精确到表或库。文章来源地址https://www.toymoban.com/news/detail-598260.html

到了这里,关于深入理解mysql的锁和mvcc的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MYSQL篇】mysql中相关锁和MVCC详解

    数据库的锁是在多线程高并发的情况下用来保证数据稳定性和一致性的一种机制。MySQL 根据底层存储引擎的不同,锁的支持粒度和实现机制也不同。MyISAM 只支持表锁,InnoDB 支持行锁和表锁。目前 MySQL 默认的存储引擎是 InnoDB,这里主要介绍 InnoDB 的锁。上一篇文章,我们对

    2024年02月10日
    浏览(31)
  • 深入理解数据库事务:确保数据完整性与一致性

    在现代信息系统中,数据是至关重要的资产之一。作为一名后端开发人员,与数据库的交道必不可少,为了确保数据的完整性、一致性和可靠性,数据库引入了事务的概念。本次将带您深入了解数据库事务的重要性、特性以及如何在应用程序中正确地使用事务来维护数据的稳

    2024年02月12日
    浏览(42)
  • 数据库中的锁

    提及事务之间的相互影响时,介绍了脏读、幻读等几种类型的数据错误,为更好避免发生这些错误,引入了对资源的锁定。锁定的存在使得一个事务对他自己的数据块进行操作时,另外一个事务不能插足这个数据块。 锁的分类 从数据库系统的角度,锁模式可分为以下6 种类型

    2024年02月13日
    浏览(36)
  • 【Java 进阶篇】深入理解 JDBC:Java 数据库连接详解

    数据库是现代应用程序的核心组成部分之一。无论是 Web 应用、移动应用还是桌面应用,几乎都需要与数据库交互以存储和检索数据。Java 提供了一种强大的方式来实现与数据库的交互,即 JDBC(Java 数据库连接)。本文将深入探讨 JDBC 的各个方面,从基本概念到实际编程示例

    2024年02月07日
    浏览(56)
  • 探索SQL深入理解数据库操作的关键概念与技巧【文末送书】

    SQL(Structured Query Language,结构化查询语言)是一种用于管理关系型数据库的标准化语言。无论是在开发应用程序、进行数据分析还是进行数据库管理,掌握SQL都是至关重要的。本文将从入门级别开始,逐步引导您了解SQL语言的基础知识,直到掌握高级技巧。 创建数据库 首先

    2024年04月22日
    浏览(70)
  • MVCC-数据库

    事务,由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。 假如A转账给B 100 元,先从A的账户里扣除 100 元,再在 B 的账户上加上 100 元。如果扣完A的100元后,还没来得及给B加上,银行系统异常了,最后导致A的余额减少

    2024年02月06日
    浏览(39)
  • 详解数据库的锁机制及原理

    本图源自CSDN博主:Stephen.W 数据库锁一般可以分为两类, 一个是悲观锁,一个是乐观锁 乐观锁一般是指用户自己实现的一种锁机制,假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用

    2024年02月05日
    浏览(40)
  • 【MySql系列】深入解析数据库索引

    MySQL索引是数据库中一个关键的概念,它可以极大地提高查询性能,加快数据检索速度。但是,要充分发挥索引的作用,需要深入理解它们的工作原理和使用方式。 在本文中,我们将深入解析MySQL索引,探讨它们的重要性、类型、创建、维护以及最佳实践。 在数据库中,索引

    2024年02月08日
    浏览(71)
  • mysql 海量数据设计:对数据库存储有深入研究

    索引: 聚簇索引 二级索引 联合索引:最左匹配原则、自动优化顺序 索引优化方向: 存储空间 主键选择:自增主键、随机主键、业务主键 如何设计一个雪花算法: 正数 + 时间戳 + 机器id(固定) + 服务id + 序号 雪花算法优点: 高并发分布式环境下生成不重复 id,每秒可生成百

    2023年04月24日
    浏览(39)
  • 什么是数据库锁(Lock)?有哪些类型的锁

    数据库锁(Lock)是在数据库管理系统中用于管理并发访问数据的重要机制。它们确保了多个用户或事务可以同时访问数据库,同时保护数据的完整性。在本文中,我们将深入探讨数据库锁的概念,以及常见的数据库锁类型和用法。 数据库锁是一种机制,用于协调多个并发事

    2024年02月07日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包