4 Database Flashcards

1
Q

Transaction的四个特性是什么?

A
  1. 原子性(Atomicity): 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部 完成,要么完全不起作用;
  2. 一致性(Consistency): 执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是 相同的;
  3. 隔离性(Isolation): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务 之间数据库是独立的;
  4. 持久性(Durability): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据 库发生故障也不应该对其有任何影响。
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

4.1.9 并发事务带来哪些问题?

A

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

丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数据, 那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修 改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取 A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

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

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

不可重复读和幻读区别:
不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点在于新增或者 删除比如多次读取一条记录发现记录增多或减少了。

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

事务隔离级别有哪些?

A

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

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

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

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

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

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

什么是缓存雪崩? 有哪些解决办法?

A

简介:缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大 量请求而崩掉。

事前:尽量保证整个 redis 集群的高可用性,发现机器宕机尽快补上。选择合适的内存淘汰策 略。
事中:本地ehcache缓存 + hystrix限流&降级,避免MySQL崩掉
事后:利用 redis 持久化机制保存的数据尽快恢复缓存

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

什么是缓存穿透?

有哪些解决办法?

A

缓存穿透说简单点就是大量请求的 key 根本不存在于缓存中,导致请求直接到了数据库上,根本没有 经过缓存这一层。举个例子:某个黑客故意制造我们缓存中不存在的 key 发起大量请求,导致大量请 求落到数据库。

有哪些解决办法?

1) 缓存无效 key : 如果缓存和数据库都查不到某个 key 的数据就写一个到 redis 中去并设置过期时 间,具体命令如下:SET key value EX 10086。这种方式可以解决请求的 key 变化不频繁的情 况,如果黑客恶意攻击,每次构建不同的请求key,会导致 redis 中缓存大量无效的 key 。很明显, 这种方案并不能从根本上解决此问题。如果非要用这种方式来解决穿透问题的话,尽量将无效的 key 的过期时间设置短一点比如 1 分钟。
2) 布隆过滤器:布隆过滤器是一个非常神奇的数据结构,通过它我们可以非常方便地判断一个给定数 据是否存在与海量数据中。我们需要的就是判断 key 是否合法,有没有感觉布隆过滤器就是我们想要 找的那个“人”。具体是这样做的:把所有可能存在的请求的值都存放在布隆过滤器中,当用户请求过 来,我会先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信 息给客户端,存在的话才会走下面的流程。

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

如何保证缓存与数据库的双写一致性?

A

最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern。

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先删除缓存,再更新数据库。

ref:https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-consistence.md

How well did you know this?
1
Not at all
2
3
4
5
Perfectly