数据库事物

数据库事物

1.事物的四大特性(ACID)

原子性:事物是最小的执行单位,不允许分割,事物的原子性确保动作要么全部完成,要么完全不起作用。

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

隔离性:并发访问数据库时,一个用户的事物不能被其它事物干扰,各并发事物之间数据库是独立的。

持久性:一个事物被提交之后,对数据库种的数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

**2.什么是脏读?幻读?不可重复读? **

脏读:某个事物已更新一份数据,另一个事物在此时获取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事物所读取的数据据就会是不正确的。

不可重复读:在一个事物的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事物更新的原有的数据。

幻读:在一个事物的两次查询种数据笔数不一致,例如有一个事物查询了几列数据,而另一个事物却在此时插入了新的几列数据,先前的事物在接下来的查询中,就会发现有几列数据是它先前所没有的。

3.什么是事物的隔离级别?MySQL默认的隔离级别是什么?

为了达到事物的四大特性,数据库定义了四种事物隔离级别,有低到高一次是Read uncommitted,Read committed,Repeatable read,Serializable这四个隔离级别可以逐个解决脏读、不可重复读,幻读这几个问题

隔离级别 脏读 不可重复读 幻读
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE

Mysql默认采用的是REPEATABLE隔离级别Oracle默认采用的是READ-COMMITTED隔离级别

事物的隔离机制的实现基于锁机制和并发调度,其中并发调度使用的是MVVC(多版本并发控制),通过保存修改的旧版本信息来支持并发一致性读和回滚等特性

隔离级别越低,事物请求的锁越少,所以大部分数据库系统的隔离界别都是READ-COMMITTED,InnoDB存储引擎默认使用的是REPEATABLE-READ并不会有任何性能损失,InnoDB存储引擎在分布式事物的i情况下一般会用到SERIALIZABLE隔离级别

4.隔离级别与锁的关系

在READ-UNCOMMITTED级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突。
在READ-COMMITTED级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁。
在REPEATABLE-READ级别下,读操作需要加共享锁,但是在事物提交之前不会释放共享锁,必须等待事物执行完毕以后才释放共享锁
SERIALIZABLE是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事物完成。

5.按照锁的粒度分数据库锁有哪些?锁机制与InnoDB锁算法

在关系型数据库中,可以按照锁的粒度把数据库锁分为行级锁(InnoDB引擎)、表级锁(MyISAM引擎)和页级锁(BDB引擎)

MySIAM和InnoDB存储引擎使用的锁:

MySIAM采用表级锁
InnoDB支持行级锁和表级锁,默认为行级锁,InnoDB是基于引擎来完成行锁

行级锁:是MySQL中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁,能减少数据库操作的冲突,加锁粒度最小,加锁开销最大,行级锁分为共享锁和排他锁。(开销大、加锁慢、会出现死锁,锁定粒度小,锁冲突概率低,并发度高)

表级锁:是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它的实现简单,资源消耗少,被大部分MySQL引擎支持,常使用的MyISAM与InnoDB都支持表级锁定,表级锁定分为表共享读锁(共享锁)与表独占锁(排他锁)。(开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低)

页级锁:页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁,表级锁速度快,但冲突多,行级锁冲突少,但速度慢,所以折衷的页级,一次锁定相邻的一组记录。(开销和加锁时间介于表锁和行锁之间,会出现死锁,锁定粒度介于表锁和行锁之间,并发度一般)

6.什么是死锁?如何解决?

死锁是两个或多个事物在同一资源上互相占用,并请求对方的锁定的资源,从而导致恶性循环的一种现象。

解决死锁的办法:

如果不同的程序会并发存取多个表,按照相同的顺序访问表
在同一个事物中,尽可能做到一次锁定所需要的所有资源,减少死锁产生的概率
对于容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率
如果业务处理不好可以用分布式事物锁或者乐观锁

7.什么是乐观锁和悲观锁?如何实现?

乐观锁和悲观锁是并发控制的主要采用的技术手段

悲观锁:假定会发生冲突,屏蔽一切可能违反数据完整性的操作,在查询完数据的时候就把事物锁起来,直到提交事物,实现方式:使用数据库中的锁机制

乐观锁:假定不会发生冲突,只在提交操作时检查是否违反数据的完整性,在修改数据的时候把事物锁起来,通过version的方式来进行锁定,实现方式:乐观锁一般会使用版本号机制或者CAS算法来实现

乐观锁适用于写比较少的情况下,也就是多读场景,即使冲突真的很少发生的时候,这样可以省去锁的开销,加大了系统的吞吐量
悲观锁适用于多写的情况,因为这种情况下经常产生冲突,会导致上层应用会不断进行retry,反倒降低了系统性能,所以一般多写的场景下用悲观锁就比较合适

作者:XinyueRao

相关推荐

Mockjs让模拟数据丰富多彩

Mockjs让模拟数据丰富多彩

在这里插入图片描述

python处理excel表格数据

采集 58同城 房产数据信息 | Java爬虫 & Jsoup

采集 58同城 房产数据信息 | Java爬虫 & Jsoup

C#获取数据库中的 第一行 第一列中的值