这几天面试多次被问到了数据库事务机制、隔离级别、乐观锁悲观锁类的问题,之前对这些只能说有所了解,有些概念还停留在记忆层面,没有理解,所以回答的不好。后面翻书学习了下,理解了一些东西,在此做一个记录。
 
什么是事务?
事务我理解的是一个完整的业务行为,一个业务行为可能包含多个动作,这个完整的动作就构成一个事务。比较经典的例子是银行转账,A账户转到B账户,需要两个动作:A账户减,B账户加,必须保证这两个动作要么都做,要么都不做。
事务具有ACID特征,具体包括:
  • 原子性(atomicity):原子性是说事务的不可分割,要么全成功,要么全失败,不可部分成功,部分失败。半途失败的情况下,需要打扫战场,也就是数据回滚。
  • 一致性(consistency):一致性是说事务的最后结果,要保证数据上没有异常。一致性是强调结果,是建立在原子性上实现的,也就是说能保证原子性,那就会有一致性的结果。
  • 隔离性(isolation):隔离性是说事务没有提交前对其他事务是不可见的,事务间数据是隔离的(当然不同级别隔离程度不一样)。
  • 持久性(durability): 事务提交后会持久化,可以长久保存。
 
事务隔离级别
了解事务的隔离级别之前,需要明白数据读取的几个概念:
  • 脏读:就是读到了别人还没提交的数据。
  • 可重复读:就是同一个事物内的两次查询,中间如果别人修改了查询内的记录且提交了,对第二次查询是不可见的,不会出现同条记录两次查询不一致问题。
  • 幻读:就是一个事物内的两次查询,中间如果别人增加了记录并且提交了,第二次查询能查询到的,会出现和第一次记录不一致的现象。
 
事务的控制分很多个级别,级别的高低决定隔离的程度,MySQL中分四个级别:
  • 读未提交:这种级别是最低的,A事务的修改没有提交对B事物是可见的,会出现数据的脏读,一般情况下不会用到此种类型。
  • 读已提交:A事物的修改提交后才对B可见,这种情况会出现数据的幻读的问题,两次查询的结果不一样。
  • 可重复读:是MySQL默认的级别,这种级别事物内的两次查询,中间其他修改了某条记录,对其他事务是不可见的,保证了重复查的情况下同条记录的一致性,但是对于新增的情况其他事务是可见的,所以还是会出现新增幻读的现象。
  • 可串行化:事务之间是串行执行的,对查询到的每条记录都加锁,会出现阻塞的情况,并发情况下会造成严重的性能问题,所以一般也不会用到这种类型。
隔离级别一览图
 
事务的隔离实现
事务当中的隔离是通过两种方式控制:一种是锁的方式,通过时间上的挫开达到隔离;另一种是版本控制的方式,记录多个版本达到隔离。
 
1、锁
MySQL当中的锁分读锁和写锁,读锁因为是读取数据所以可以多个同时读取同一份数据,具有共享性质;写锁涉及到数据的变动,所以和其他写锁和读锁是相冲突的,具有排他性质。
从锁的粒度上分表级锁和行级锁,表锁一般发生在对表结构的修改或对全表更新的时候,会阻塞所有对这张表的读写操作;行级锁一般发生在指定记录更新的时候,只会锁定指定记录。锁的粒度越小并发度越高,能优先行级锁尽量不要表锁,和程序中锁的粒度是一样的原则。
 
2、多版本并发控制
MySQL为了性能考虑除了行级锁以外还是另外一种方式,多版本并发控制,这中控制是由存储引擎实现。
书中说明了InnoDB一种简单的实现方式,这种方式是采用一条记录多个版本的方式,每条记录上增加了两个隐藏列,一个是创建版本号,一个是删除版本号,每开启一个事务都会分配一个事务版本号,事务版本号是递增的,事务内操作都会根据这个版本号比较。具体如下:
  • 查询时:查询当前事务之前存在的记录和本事务创建的记录,且没有被删除的,即:创建版本号<=当前版本号 && (删除版本号为空 || 删除版本号 > 当前版本号)
  • 插入时:记录的创建版本号为当前事务版本号。
  • 删除时:更新记录的删除版本号为当前事务版本号。
  • 更新时:插入一条新记录,创建版本号为当前事务版本号,同时把原记录删除版本号改为当前事务版本号,代表已经删除。实际上这里的更新相当于删除再加一条记录。
 
3、乐观锁和悲观锁
锁从使用的角度又分悲观锁和乐观锁,悲观锁是持有很悲观的态度,认为我查到的数据都有可能被别人修改,所以查询的时候就把这一批数据锁起来,不让别人操作;乐观锁是持有很乐观的态度,认为我查到的数据基本不可能被别人修改,所以查询的时候不锁住这批数据,修改提交的时候再确认有没有被别人修改,有种亡羊补牢,为时不晚的意思。
 
乐观锁和悲观锁的实现:
  • 悲观锁可以在数据库层面很简单的解决,利用select ... for update,在查询的时候就锁定这部分数据。
  • 乐观锁的实现较悲观锁复杂,可以在数据库在一个版本号的列,更新的时候版本号都+1,以此来确认我查出来的数据后面有没有别人修改,已修改的不更新或程序抛一个异常。
使用乐观锁还是悲观锁:
从性能的角度考虑乐观锁性能更好,在查询到更新这段时间没有锁定操作,但是实现起来没有悲观锁简单,可能出错。所以要考虑的因素是系统的并发高不高?出现冲突的概率有多大?并发高的情况下选用乐观锁更好,反之选用悲观锁这种简单的方式更好。
 
 
 

关于MySQL数据库事务的机制学习总结的更多相关文章

  1. MySQL数据库事务剖析

    MySQL数据库事务剖析 事务就是一组原子性的SQL查询,是一个独立的执行单元.事务内的语句,要么全部执行成功,要么全部执行失败. 1.事务的标准特征 一个运行良好的事务处理系统,必须具备原子性.一致 ...

  2. Mysql数据库事务隔离级别

    事务(transaction)是数据库管理系统的执行单位,可以是一个数据库操作(如Select操作)或者是一组操作序列.事务ACID属性,即原子性(Atomicity).一致性(Consistency ...

  3. mysql数据库事务详细剖析

    在写之前交代一下背景吧! 做开发也好久了,没怎么整理过知识,现在剖析一下自己对数据库事务的认识,以前用sqlserver,现在转java后又用mysql.oracle.我这块就主要解释一下mysql数 ...

  4. MySql数据库事务正常提交,回滚失败

    问题:在初次练习Mysql数据库事务时,事务正常提交,但是在遇到异常应当回滚时,回滚失败. 代码如下: //2.更新操作. public void update(Connection conn, St ...

  5. Mysql数据库事务的隔离级别和锁的实现原理分析

    Mysql数据库事务的隔离级别和锁的实现原理分析 找到大神了:http://blog.csdn.net/tangkund3218/article/details/51753243 InnoDB使用MV ...

  6. mysql数据库锁的机制-及事务事件

    事务隔离级别,脏读.不可重复读.幻读,乐观锁.悲观锁(共享锁.排它锁) 数据库事务具有四个特征,分别是原子性(Atomicity).一致性(Consistency).隔离性(Isoation).持久性 ...

  7. MySQL数据库事务各隔离级别加锁情况--read uncommitted篇(转)

    本文转自https://m.imooc.com/article/details?article_id=17291,感谢作者 1.目的 1.1 合适人群 1.数据库事务特征我只是背过,并没有很深刻的理解 ...

  8. mysql数据库事务隔离原理

    今天在学习JDBC的时候看到了关于MySQL的事务的隔离级别的问题,感觉内容挺高级的,所以记录一篇文章,以备后面使用. 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说 ...

  9. MySQL 数据库事务与复制

    好久没有写技术文章了,因为一直在思考 「后端分布式」这个系列到底怎么写才合适. 最近基本想清楚了,「后端分布式」包括「分布式存储」和 「分布式计算」两大类. 结合实际工作中碰到的问题,以寻找答案的方式 ...

随机推荐

  1. 跟随大神实现简单的Vue框架

    自己用vue也不久了,学习之初就看过vue实现的原理,当时看也是迷迷糊糊,能说出来最基本的,但是感觉还是理解的不深入,最近找到了之前收藏的文章,跟着大神一步步敲了一下简易的实现,算是又加深了理解. 原 ...

  2. GPU PassThrough in KVM

    实现步骤 环境 OS: # cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) # uname -a Linux hyhive 3 ...

  3. NoneBot+酷Q,打造QQ机器人

    NoneBot 是一个基于 酷Q 的 Python 异步 QQ 机器人框架,它会对 QQ 机器人收到的消息进行解析和处理,并以插件化的形式,分发给消息所对应的命令处理器和自然语言处理器,来完成具体的功 ...

  4. CPU踩点图

    CPU占比探测用js来检查当前系统cpu的占用比例,通过 setTimeout 的方式探测 CPU 的大小,这样可以实现网页游戏中动画等耗时操作的自动调节.这个原理是很多人都知道的,就是用JS来踩点. ...

  5. Android 添加framework资源包

    为Android系统添加一个新的资源包 概述 传统的Android系统只有一个framework-res.apk资源包,第三方厂商在进行rom定制时会直接修改framework res资源,达到适配目 ...

  6. C++走向远洋——27(项目三,时间类)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:time.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  7. java反序列化-ysoserial-调试分析总结篇(3)

    前言: 这篇文章主要分析commoncollections3,这条利用链如yso描述,这个与cc1类似,只是反射调用方法是用的不是invokeTransformer而用的是InstantiateTra ...

  8. 使用 GitHub 开源项目申请 IntelliJ License

    一.写在前面 这次要介绍的是通过使用 GitHub 上的开源项目来申请 IntelliJ Pycharm 的正版 License,只需在 GitHub 上准备一个维护超过3个月的开源项目,就能免费使用 ...

  9. 自定义 ---UICollectionViewLayout-正N变形居中布局

    1. 自定义UICollectionLayout ---- 正三角形居中布局 支持多个图形的自动布局 2. 自定义UICollectionLayout ---- 正方形居中布局 滚动展示的区域 3.  ...

  10. GO - if判断,for循环,switch语句,数组的使用

    1.if - else if - else的使用 package main import "fmt" func main() { // 1.简单使用 var a=10 if a== ...