11

理解mysql的事务隔离级别

 2 years ago
source link: https://segmentfault.com/a/1190000041473349
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

理解mysql的事务隔离级别

发布于 今天 10:49

考研分数落定,今年无缘,着手准备春招。说到今年考研,分数可谓水涨船高,去年本校专硕270就能进,今年一舍友考了270,排名排到了140名(报的专业要70个),进复试基本无望,估计考本校分数线能到290。
走校招的话公司一般面试问题方方面面,重点离不开算法和语言的基础知识。大厂非常重视校招生的算法能力,因为校招生项目经验少,而大厂项目用户量大。算法这个就是在力扣上多做题,多了解答案思路。
语言基础知识这块,就得多看书,有些东西是我们平常开发接触不到的,面试官又爱问。面试就是这样,面试造火箭,工作拧螺丝。喜硕学长推荐了两本书,一本《深入浅出mysql》,翟振兴著,一本《深入理解jvm虚拟机》,周志明著。粗略看了一下《深入浅出mysql》更像是一本mysql的字典,里面从基本sql语句到sql优化维护都有涉及,心学数据库没有教材买本这个书看也可以,肯定比学校发的教材强,学校发的大多都是学校老师自己写的。并且里面举例比较多,好理解。《深入理解jvm虚拟机》可以当扩展读物看,里面讲了一些java底层一些知识,比如new一个对象具体发生了什么,jvm如何进行内存回收,jvm调优,我们不知道这些东西也不影响我们用java开发。并且举例较少,建议有一定java基础和操作系统知识基础再来看这本书。

mysql锁概述

锁是协调各个进程或者线程并发访问一个资源的重要机制。一个好的锁机制,不仅保证了数据并发访问的一致性、有效性。并且也尽量减少并发性能的影响。
我们知道InnoDB引擎相对于其他来说支持事务。事务是一组SQL语句组成的逻辑处理单元,具有4个特性,通常简称为事务ACID属性。

  • 原子性:事务是一个原子操作单元,要么全部执行,要么全部不执行。
  • 一致性:在事务开始和完成时,数据要保持一致状态。就是说在事务开始和完成时,数据保持一个正确的状态。
  • 隔离性:数据库提供一定的隔离机制,保证事务在不受外部事务影响的环境运行。这意味着事务处理过程中的中间状态对其他事务来说是不可见的。
  • 持久性:事务完成后,对于数据的修改时永久性的。
    我们拿经典的银行转帐来理解事务。
    比如说张三账户上想往李四账户上转1000块钱。
    那么用sql语句就是这样的

    update bank set balance = balance - 1000 where name = '张三';
    update bank set balanc = balance + 1000 where name = '李四';

    如果我们将其中的一个字段打错,那么其中一条语句无法正确执行。

    update bank set balance = balance - 1000 where name = '张三';
    update bank set balance = balance + 1000 where name = '李四';

    那么会照成张三少了1000块钱而李四没有多1000块钱情况。
    如果加入事务则不会发生这种情况。
    原子性保证要么两条语句都执行,要么都不执行。
    一致性保证钱转帐过程的开始和完成时总数保持不变,且余额都不会少于0。
    隔离性保证这个事务执行完之前,不会对其他事务造成影响。
    持久性保证事务完成后对钱的修改时永久的。

    并发事务带来的问题

    并发事务增加了数据库利用率,提高吞吐量,也带来了一些问题。

  • 更新丢失:

    事务A事务B开启一个事务开启一个事务将张三账户余额加200将张三账户余额加500提交//提交

    这造成了两个人同时给张三存钱,一个人存200,一个人存500,结果账户只多了500,200没了。

  • 事务A事务B开启一个事务开启一个事务查询张三余额为1000 如果查询的结果大于等于1000则将张三账户余额减1000查询张三余额为1000/如果查询的结果大于等于1000则将张三账户余额减1000/提交提交/
  • 不可重复读:

    事务A事务B开启一个事务开启一个事务查询张三余额为1000//将张三账户余额加500/提交查询张三余额为1500/提交/

    这造成事务A两次查询结果不一致,不知道已哪个为准。

  • 事务A事务B开启一个事务开启一个事务查询姓张的人的余额,查到张三余额为1000//新建个账户叫张四,余额为0/提交查询姓张的人的余额,查到张三余额为1000,张四余额为0/提交/

    更新丢失只要保证一个事务在对数据更新提交之前,另一个事务不能更改数据。这个主要靠应用层面来解决。
    脏读,不可重复读,幻读,需要靠数据库提供的一定的事务隔离机制来解决。数据库实现数据隔离方式,基本分以下两种:

  • 一种是在读取数据前,对其加锁,阻止其他事务对数据进行更改。
  • 一种是不加任何锁,通过一定机制生成一个数据请求时间点的数据快照,并用这个快照来提供一定级别的数据读取。从用户角度看,好想数据库可以提供统一数据不同版本,这种技术叫做数据多版本并发控制,也就是MVCC。关于MVCC可以看这篇文章这篇文章
    数据库事务隔离越严格,并发副作用越小,但付出代价越大。这是一个权衡的过程。未来解决隔离与并发矛盾,sql定义了4个事务隔离级别,应用根据自己业务逻辑要求,选择不同隔离级别来平衡隔离与并发的矛盾。

    脏读不可重复读幻读未提交读 READ-UNCOMMITTED是是是已提交读 READ-COMMITTED否是是可重复读 REPEATABLE-READ否否是可序列化 SERIALIZABLE否否否

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK