java面试:有了解过数据库事务吗,能详细讲一讲么
作为数据库中的核心概念,数据库事务保证了在并发环境下mysql的正常执行,因此在面试当中,数据库事务可谓是常客了,今天小编就来分享一下关于数据库事务的相关知识点。
1.数据库事务的定义
事务是数据库管理系统(DBMS)中的一个核心概念,它确保了一系列的数据库操作要么全部成功执行,要么全部不执行,从而维护数据的完整性和一致性,这里我会举一个例子,来对这个问题做详细的说明。
假设一个用户来银行用账户A转账了1000给账户B,但这样一个转账操作当中是两步操作,第一就是账户A扣减1000的余额,而账户B在同时余额增加1000。但在这样的两步操作中,不论是余额扣减亦或是余额增加只要哪一步操作失败,假设另一个操作成功,都会导致A与B的账户的总余额的值是不一致的。
因此事务通俗来说就是一系列sql构成的一个整体,要么全部成功要么全部失败,以此来保证数据安全,事务并发的问题。
2.数据库的四大特性(ACID)
事务的四大性质分别是原子性,一致性,持久性,隔离性,接下来我会分别对这几个性质做详细的讲解
原子性
定义:事务中的所有操作要么全部成功提交,要么全部失败回滚,不存在中间状态。
实现机制:数据库通过日志undo log来记录事务的修改操作,如果事务失败,系统可以利用这些日志将数据恢复到事务开始前的状态。
一致性
定义:事务执行前后,数据库的数据必须处于一致的状态,不能出现前后数据总和不一致。
注意:一致性是事务追求的最终目标,原子性、隔离性和持久性共同作用,都是为了实现一致性。
隔离性
定义:多个事务并发执行时,每个事务都感觉不到其他事务在并发执行,各个事务的数据不能相互影响
实现机制:数据库通过日志undo log+MVCC去实现
持久性
定义:一旦事务提交,它对数据库的修改就是永久性的,即使系统断电、宕机也不会丢失。
实现机制:数据库通过日志redo log记录事务的修改操作。在事务提交前,相关的日志必须被写入磁盘,确保数据的持久性。
而数据库的基础就是基于这四个性质为底层来实现的。
3.数据库常见的并发问题
在数据库执行某些操作时,假设没有事务隔离,那就会出现许多的并发操作问题,接下来我们就对这些并发问题做一些讲解:
脏读:一个事务读取了另一个事务未提交的数据,最终可能导致数据保证不了一致性。
不可重复读:一个事务在读取同一数据时,由于另一个事务的对共享数据做了修改,导致两次读取的结果不一致。
幻读:一个事务在读取某个范围的数据时,由于另一个事务的插入或删除,导致数据读取时发现数据突然出现或出现突然消失的问题。
4.事务的隔离级别
为了解决如上的并发问题,数据库事务提供了四大隔离级别,我们也对这四种隔离级别由低到高来进行讲解。
读未提交:最低级别,允许读取尚未提交的数据,无法解决脏读,不可重复读,幻读问题,实际并不怎么使用。
读已提交:只允许读取并发事务已经提交的数据,可以避免脏读,但无法解决不可重复读与幻读问题。
可重复读:是mysql默认的隔离级别,同一事务中读取同一数据会生成数据快照,除非数据被本事务自身修改,否则数据的读取永远一致,可以避免脏读和不可重复读,但依旧出现幻读。
串行化:最高级别,强制事务串行执行,禁止事务并发执行,也就不在存在并发问题,完全避免脏读、不可重复读和幻读,但在并发量过高时,很可能产生大量的超时和锁竞争,性能很低。
从中我们会得到一个规律,事务的隔离级别越高,所说越能保证数据的完整和一致性,但同时也意味着性能会越来越低。
5.事务隔离级别如何实现
这里我们来简单讲一下事务隔离级别的实现,帮助大家了解的更为深刻。
读未提交:不需要具体实现,因为并发的事务本身就是读未提交。
读已提交:通过MVCC的多版本并发控制,在事务查找数据后,每次都会会生成一个被称之为readview的数据快照,而事务被设置为每次都读取这个最新的版本的数据,因此保证了读到的数据是最新的,保证了读取的数据是已提交的。
可重复读:通过MVCC的多版本并发控制,在事务查找数据后,会生成一个被称之为readview的数据快照,也是一个数据版本,与读已提交不同的是事务被设置为只能读取这个版本的数据,因此保证了读到的数据是永远保持一致的。
串行化:为事务加悲观锁,只有获取到锁的事务才能执行,其余的事务需要在这段时间内等待阻塞,这样就保证了事务的串行执行。
今天的分享就到这里了,希望这篇博客能给你一些帮助,让你对关于mysql事务的问题得到进一步的提升,在面试的时候能从容面对面试官。