数据库面试

数据库中的事务是什么?

事务(transaction)是作为一个单元的一组有序的数据库操作。如果组中的所有操作都成功,则认为事务成功,即使有一个操作失败,事务也不成功。如果所有操作完成,事务则提交,其修改将作用于所有其他数据库进程。如果一个操作失败,则事务回滚,该事务所有操作的影响都将取消。

事务可以使一组操作要么全部成功,要么全部失败。事务的目的就是为了保证数据最终一致性

例:我给你转了100元。那么我银行卡扣100元,你的银行卡多100元。事务就是保证我的余额扣减和你的余额增添是同时成功或者同时失败。

事务特性(ACID):

原子性(Atomicity):事务是最小的执行单位,不可分割,事务要么全部被执行,要么全部不被执行

原子性由undo log日志来保证,因为undo log记载着数据修改前的信息。如果要insert一条数据,那么undo log会记录一条对应的delet日志。我们要update一条数据时,那么undo log会记录之前旧值的update记录。如果执行事务过程中出现异常情况,那执行回滚。InnoDB引擎就是利用undo log记录下的数据,来将数据恢复到事务开始之前。

一致性(Consistency):执行事务前后,数据保持一致,多个事务对同一数据读取的结果是相同的。

一致性就是使用事务的目的,而隔离性、原子性、持久性均是为了保障一致性的手段,保证一致性需要由应用程序代码来保证。比如,如果事务在发生的过程中,出现了异常情况,此时就得回滚事务,而不是强行提交事务导致数据不一致。

隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。如果多个事务可以同时操作一个数据,那么就会产生脏读、不可重复读、幻读的问题。

于是,事务与事务之间需要存在一定的隔离。在InnoDB引擎中,定义了四种隔离级别供我们使用:读未提交、读已提交、可重复读、串行。不同的隔离级别对事务之间的隔离性是不一样的(级别越高事务隔离性越好,但性能就越低),而隔离性是由MySQL的各种锁来实现的,只是它屏蔽了加锁的细节。

持久性(Durability):事务正确提交后,其结果将永久保存在数据库中,即使事务提交后有了其他故障,事务的处理结果也会得到保存。

持久性由redo log日志来保证,当我们要修改数据时,MySQL是先把这条记录所在的页找到,然后把该页加载到内存中,将对应记录进行修改。为了防止内存修改完了,MySQL就挂掉了(如果内存改完,直接挂掉,那这次的修改相当于就丢失了)。MySQL引入了redo log,内存写完了,然后会写一份redo log,这份redo log记载着这次在某个页上做了什么修改。即使MySQL中途挂掉了,我们还可以根据redo log来对数据进行回复。redo log是顺序写的,写入速度很快。并且它记录的是物理修改(xxxx页做了xxx修改),文件体积很小,恢复速度很快。

并发事务带来哪些问题?

脏读(Dirty read):当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另一个事务也访问了这个数据,然后使用了这个数据。因为这个数据时还没有提交的数据,那么另一个事务读到的这个数据时“脏数据”,依据“脏数据”所做的操作可能时不正确的。

丢失修改(Lost to modify):当一个数据读取一个数据时,另一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内修改结果就被丢失,因此称为丢失修改。

不可重复读(Unrepeatableread):当一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

幻读(Phantom read):幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时,在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复读和幻读区别:

不可重复读的重点是修改,幻读的重点在于新增或者删除。

例:(同样的条件,你读取过的数据,再次读取出来发现值不一样了):事务1中的A先生读取自己的工资为1000的操作还没完成时,事务2中的B先生就修改了A的工资为2000,导致A再读自己的工资时工资变为2000;这就是不可重复读。

例:(同样的条件,第1次和第2次读出来的记录数不一样):假设工资单表中工资大于2000的有4人,事务1读取了所有工资大于2000的人,共查到4条记录,这时事务2又插入了一条工资大于2000的记录,事务1再次读取时查到的记录就变成了5条,这样就导致了幻读。

事务隔离级别有哪些?MySQL默认隔离级别是?

SQL标准定义了四个隔离级别:

读取未提交(read - uncommitted):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读、不可重复读。

读取已提交(read - committed):允许读取并发事务已经提交的数据,可以阻止脏读,但幻读和不可重复仍有可能发生。

可重复读(repeatable - read):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

可串行化(seriakizable):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依此逐个执行,这样事物之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读、幻读。

MySQL InnoDB 存储引擎的默认支持的隔离级别是可重复读。

MySQL InnoDB引擎的索引

使用索引可以加快查询速度,将无序的数据变成有序(有序就能加快检索速度)

在InnoDB引擎中,索引的底层数据结构是B+树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值