100天面试——第二天:数据库事务和乐观锁
Posted 100天面试
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了100天面试——第二天:数据库事务和乐观锁相关的知识,希望对你有一定的参考价值。
100天面试任意门
更多请点击最下方“阅读原文”
本文来自慕课网《Google面试官亲授 升级java面试》课堂笔记。
汇总网络上大佬的文章做学习参考。
如有侵权告知速删。
事务
事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在计算机术语中,事务通常就是指数据库事务。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
持久性(Durability):一个事务一旦提交,他对数据库的修改应该永久保存在数据库中。
这四个特性我认为最重要的是:隔离性(Isolation),下面介绍一下数据库事务的四中隔离级别。
Read uncommitted(未授权读取、读未提交):
如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
避免了更新丢失,却可能出现脏读。也就是说事务B读取到了事务A未提交的数据。
脏读:一个事务读取到了另一个事务未提交的数据操作结果。
Read committed(授权读取、读提交):
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
该隔离级别避免了脏读,但是却可能出现不可重复读。事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
不可重复读(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。
在这里区分下for_update和rowid的区别,虽然两个都是我们一般修改数据时候用,但是for_update会对你查询出来的结果加上锁,而rowid就没有这样的机制。
Repeatable read(可重复读取):
读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过“共享读锁”和“排他写锁”实现。
幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
Serializable(序列化):
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
乐观锁
当面试官问及这个行级锁或是序列化会耗费大量资源的时候,我们可以提及“乐观锁”,乐观锁如何实现
乐观锁适用于冲突不多的情况下。
版本保护
如果其他事物抢先做了操作更改,这个条件就满足不了了,导致操作失败。
或者记录timestamp。
检查和提交要并在一行同时执行。
timestamp时间戳,老师一带而过了。而我之前每次用到这个的时候都记不住要问度娘,现在是终于会了,在这里记录一下,希望以后操作数据库的工作中别再用到这个,因为一用到这个一般就代表着有锅要背了,哈哈
首先timestamp得表不能使用别名,然后我一般的用法:
select *
from tablename as of timpstamp
to_timestamp('20180310 23:25:00','YYYYMMDD HH24:MI:SS')
where ...
100天面试任意门
更多请点击最下方“阅读原文”
以上是关于100天面试——第二天:数据库事务和乐观锁的主要内容,如果未能解决你的问题,请参考以下文章
第36讲 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景
redis08_redis的事务 multi(声明一个事务)exec(执行一个事务)redis里面为什么要有事务悲观锁和乐观锁(可以并发提高吞吐量)