- 原子性:事务作为一个整体被执行,包含在其中的对数据库的操作要么全部都执行,要么都不执行。
- 一致性:指在事务开始之前和事务结束以后,数据不会被破坏,假如A账户给B账户转10块钱,不管成功与否,A和B的总金额是不变的。
- 隔离性:多个事务并发访问时,事务之间是相互隔离的,一个事务不应该被其他事务干扰,多个并发事务之间要相互隔离。。
- 持久性:表示事务完成提交后,该事务对数据库所做的操作更改,将持久地保存在数据库之中
在JAVA中,MVCC(Multi-Version Concurrency Control,多版本并发控制)是一个并发控制的方法,它允许读和写操作无锁地并发执行。这种方法在数据库管理系统(DBMS)中特别常见,用于解决读写冲突问题,从而提高并发性能。
在MVCC中,每个数据项可以有多个版本,每个版本都与一个特定的事务相关联。当事务尝试读取数据时,它看到的是数据的一个一致性快照,即在该事务开始时的数据版本。这样,即使其他事务正在修改数据,读取事务也不会受到干扰。
当事务尝试写入数据时,它会创建一个新的数据版本,而不是直接修改原始数据。这样,其他事务仍然可以读取旧版本的数据,而不会被写操作阻塞。
通过这种方式,MVCC可以显著提高并发性能,因为它避免了读写操作之间的直接冲突。然而,它也可能增加存储和管理的复杂性,因为需要维护数据的多个版本。
需要注意的是,虽然JAVA本身不直接提供MVCC机制,但JAVA开发者可以通过使用支持MVCC的数据库产品或库来利用这种并发控制方法。
也就是说,其实 MVCC 他并不是一个实际的技术,而是属于一种方法。
那么 MVCC 解决了哪些问题呢?这也是面试里面的高频考点
MVCC 解决了哪些问题呢?
MVCC(Multi-Version Concurrency Control,多版本并发控制)主要解决了在数据库管理系统中并发访问时可能出现的读写冲突问题。具体来说,MVCC通过为数据项保留多个版本来实现以下目标:
无锁读操作:在MVCC中,读操作不需要获取锁,因为它们可以读取数据的一个一致的快照(即某个时间点的数据版本)。这意味着读操作不会受到写操作的阻塞,从而提高了并发性能。
写操作的隔离性:写操作会创建数据的新版本,而不是直接修改原始数据。这样,其他事务在写操作进行时仍然可以读取旧版本的数据,保证了事务的隔离性。每个事务都仿佛是在一个单独的数据快照上运行,彼此互不影响。
减少锁争用:由于读写操作可以并发执行,MVCC减少了锁争用的可能性。在传统的锁机制中,读和写操作可能会相互阻塞,导致性能下降。而MVCC通过避免直接锁冲突,提高了系统的吞吐量和响应速度。
一致性和可重复读:通过读取特定时间点的数据版本,MVCC可以确保事务看到一致的数据视图,即使其他事务在此期间进行了修改。这对于实现事务的一致性(C)和隔离性(I)至关重要。
需要注意的是,虽然MVCC提供了很多优势,但它也增加了数据管理的复杂性。数据库系统需要维护多个数据版本,并在适当的时候清理这些版本以释放存储空间。此外,MVCC的实现也可能增加一些额外的开销,如内存使用和垃圾回收等。
总的来说,MVCC通过多版本的方式解决了并发访问时的读写冲突问题,提高了数据库系统的并发性能和事务的隔离性。
既然我们都已经知道了 MVCC 是用来处理读写冲突问题的,那么他的实现原理是什么呢?
MVCC 实现原理是什么?
MVCC(Multi-Version Concurrency Control,多版本并发控制)的实现原理主要是为数据库中的每个数据项维护多个版本,从而使得读和写操作可以并发执行,互不干扰。以下是MVCC实现原理的关键点:
事务标识:每个事务被分配一个唯一的事务标识(Transaction ID)。这个标识可以是递增的数字或其他唯一标识符,用于区分不同的事务。
数据版本:数据库中的每个数据记录都会包含多个版本。每个版本都有一个时间戳或者事务标识,用于标识该版本的有效期。例如,当数据被修改时,系统会保留修改前的数据版本,并创建一个新的数据版本。这样,数据库中就形成了一个版本链,其中每个版本都记录了数据在某个时间点的状态。
读操作:当一个事务执行读操作时,它会根据事务开始时的状态来选择一个可见的数据版本。具体来说,系统会根据读操作开始时的事务标识或时间戳,在版本链中找到一个与该事务兼容的最新版本。这个版本必须是在事务开始之前已经提交或由该事务自身创建的。
写操作:当一个事务执行写操作时(如更新或删除),它会创建一个新的数据版本,并将事务标识或时间戳与该版本关联。这个新版本的数据仅对当前事务可见,对其他并发事务是不可见的。直到当前事务提交后,其他事务才能看到这个新版本的数据。
并发控制:MVCC通过在读操作和写操作中使用事务标识或时间戳来判断数据的可见性和一致性。由于每个事务都看到的是数据的一个一致的快照版本,因此读操作不会阻塞写操作,写操作也不会阻塞读操作。这允许多个事务在数据库上并发执行,而不会互相干扰。
Undo日志:在实现MVCC时,通常会使用Undo日志来存储旧版本的数据。当数据被修改时,原始数据会被存储在Undo日志中,以便在需要时能够回滚到之前的状态或构造出数据的早期版本。
综上所述,MVCC通过维护数据的多个版本和使用事务标识或时间戳来控制数据的可见性和一致性,从而实现了高并发性和事务隔离性。这使得多个事务可以在不完全锁定数据库资源的情况下并发执行,提高了数据库的吞吐量和用户的响应速度。