同时更改一条数据_数据库中的引擎、事务、锁、MVCC(二)
二、事务
介绍锁之前,咱们先介绍一下 什么叫做事务。
事务就是一组对数据库的一系列的操作,要么同时成功,要么同时失败。
1、事务的特性(ACID):
- 原子性:事务是整个操作,不可分割,要么都成功,要么都失败。
- 一致性:一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
- 隔离性:事务操作是相互隔离不受其他影响。
- 持久性:事务一旦提交,数据就不可改变,无法回滚。
2、高并发事务带来的问题:
- 数据丢失:两个事务同事更新一条数据,第一个事务物先提交,第二个事务后提交,第二个异常回滚,造成第一个事务更新操作也被回滚的情况。
- 第二类数据丢失:(不可重复读的特殊情况)两个事务都操作同一行,然后两个事务进行写操作,并提交。第一事务做的更改会丢失。
- 脏读:第二事务查询到第一个事务未提交更新的数据。
- 不可重复读:一个事务内两次读取同一行数据,结果得到不同的结果。由于隔离性,事务不互相影响,如果这一个事务内两次查询中间正好另一个事务更新该数据,两次结果相异不可信任。
- 虚读(幻读):一个事务在执行过程中读取到了另一个事务已提交的插入数据;即在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,即好像发生幻觉一样。
注意:
- 不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。
- 虚读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而虚读针对的是一批数据整体(比如数据的个数)。
3、事务的隔离级别:
为了解决上面的事务并发的问题,提供了数据库四中事务隔离级别:
级别从高到低依次是:
- Serializable 串行化:避免脏读、不可重复读,幻读的发生。
- Repeatable Read 可重复读:可避免脏读、不可重复读的发生。
- Read Commited 可读已提交:可避免脏读的发生。
- Read UnCommited 可读未提交:最低级别,任何情况都会发生。
Mysql默认隔离级别是:可重复读:Repeatable read。
oracle只支持seralizable和Read committed两个级别。默认的是Read committed级别。
三、数据库中的锁
事务的级别和数据库中的锁都是为了解决高并发造成数据不一致的问题。
数据库中的锁,也就是咱们常听的:悲观锁、乐观锁、表锁、行锁、临键锁、间隙锁、记录锁、共享锁、排他锁、意向共享锁、意向排他锁。
1、锁的分类:
- 锁模式分类:悲观锁、乐观锁
- 范围锁:行锁、表锁,页锁
- 算法锁:临键锁、间隙锁、记录锁;
- 属性锁:共享锁(S、读)、排他锁(X、写);
- 状态锁:意向共享锁(表锁)、意向排他锁(表锁)。
2、定义
乐观锁和悲观锁都是为了解决并发控制问题。
乐观锁:可以认为是一种在最后提交的时候检测冲突的手段。他是应用系统层面和数据的业务逻辑层次上的,利用程序处理并发问题。乐观锁的实现大部分都是基于版本控制实现的。
悲观锁:一种避免冲突的手段。悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作。悲观锁是由数据库进行实现的,要用的话直接调用数据库相关语句即可。
共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。
共享锁(读锁、S锁):共享锁指的就是对于多个不同的事务,对同一个资源共享同一个锁。主要是select
排他锁(写锁、X锁):对于多个不同的事务,对同一个资源只能有一把锁。与共享锁类型,在需要执行的语句后面加上for update就可以了。
行锁:某一行加上锁,也就是一条记录加上锁,是数据库机制上的锁。行级锁分为共享锁和排他锁两种。
表锁:给表加上锁,也就是直接锁住一张表,操作未完,不允许其他操作进行更改。
页锁:介于行锁跟表锁之间。
记录锁:他专门用来封锁某条索引记录。
间隙锁:他专门用来封锁索引记录区间。间隙锁只会锁定区间不锁定自己
临键锁:他是记录锁跟间隙锁的组合,他即封锁记录,有包含索引空间。临键锁会封锁索引记录本身,以及索引记录之前的区间。
例如:
select * from table where id=1 for update; 是记录锁,封锁的是 id=1的这条索引记录。
select * from table where id between 1 and 10 for update;是间隙锁,封锁的是Id[1.10]这个区间的索引
意向锁:意向锁是放置在资源层次结构的一个级别上的锁,以保护较低级别资源上的共享锁或排它锁。意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。
InnoDB 中的两个表锁:
意向排他锁:表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的 IS 锁。如果需要对记录 A 加共享锁,那么此时 InnoDB 会先找到这张表,对该表加意向共享锁之后,再对记录 A 添加共享锁。
意向共享锁:类似上面,表示事务准备给数据行加入排他锁,也就是说事务在给一个数据行加排他锁前必须先取得该表的 IX 锁。如果需要对记录 A 加排他锁,那么此时 InnoDB 会先找到这张表,对该表加意向排他锁之后,再对记录 A 添加排他锁。
1、意向锁是 InnoDB 自动加的,不需要用户干预。
2、共享锁跟排他锁都是行锁,锁的都是行记录。意向共享锁跟意向排他锁都是表锁,锁的都是表记录。
3、行锁与表锁之间的区别
- 锁的粒度就是指锁的生效范围。他们的名字代表了颗粒度的大小。
- 表级锁:开销小,加锁快;不会出现死锁;锁粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁粒度最小,发生锁冲突的概率最低,并发度最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁粒度界于表锁和行锁之间,并发度一般。
4、加锁
- 添加X锁:select ... for update
- 添加S锁:select ... in share mode
注意:
InnoDB 的锁,与索引类型,事务的隔离级别相关。InnoDB 到底是行锁还是表锁取决于你的 SQL 语句。如果查询没有命中索引,也将退化为表锁。InnoDB 的行锁是实现在索引上的,而不是锁在物理行记录上。所以如果访问没有命中索引,也无法使用行锁,将要退化为表锁。
参考网站:
数据库事务的四大特性以及事务的隔离级别:https://www.cnblogs.com/fjdingsd/p/5273008.html
事务特性和并发带来的问题:http://www.cnblogs.com/stone-learning/p/9243110.html
数据库中乐观锁、悲观锁、共享锁和排它锁的理解:https://www.liangzl.com/get-article-detail-1144.html
数据库中的事务和锁(乐观、悲观锁,共享、排他锁,死锁):https://blog.csdn.net/woshiluoye9/article/details/68954515
MySQL锁详解:https://www.cnblogs.com/luyucheng/p/6297752.html
一分钟明白各种SQL语句加的什么锁——《深究Mysql锁》:https://blog.csdn.net/zcl_love_wx/article/details/82386143
Innodb锁的类型:https://blog.csdn.net/qq_33330687/article/details/82425120
同时更改一条数据_数据库中的引擎、事务、锁、MVCC(二)相关推荐
- mybatis insert 重复数据2条_Mybatis框架lt;增gt;:添加一条数据到数据库中,insert...
在以上框架中,前面所搭建好的框架全部固定好,接下来,我们在此基础上实现功能使用insert添加一条数据到数据库中(1)在UserMapper接口中添加对应方法,//在数据库表中增添一条数据,返回为in ...
- 同时更改一条数据_数据仓库amp;面试总结
一.数据仓库分为几层?负责什么职责?为什么要分层? 1.数据仓库分为4层: ODS层 (原始数据层) DWD层 (明细数据层) DWS层 (服务数据层) ADS层 (数据应用层) 2.主要负责职责,如 ...
- mysql数据库每秒能写入多少条数据_数据库插入速度能有50W每秒吗
写入速度 MySQL每秒可以插入50w条记录吗? 带着疑问,我们一起看看mysql每秒可以插入多少条记录? 要回答这个问题,首先要考虑影响mysql插入速度的因素有哪些? 硬盘的速度,网卡的速度,写入 ...
- mysql 获取一条数据_MySQL数据库中随机获取一条或多条记录
在开发过程中遇到了一个问题,使用MySQL数据库,用SQL语句在表中随机获取一条或多条数据,看似简单,但是往深层研究的话还是很有深度的,查了好多资料,接下来给大家分享一下: 1. 随机获取单条数据 S ...
- 同一个事务里面对同一条数据做2次修改_MySQL事务与MVCC如何实现的隔离级别
有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...
- mysql查询第11到20条数据_数据库查询语句怎样查询一个表中的第15到第20条数据...
展开全部 用row_number来查询. 具体方法如下:62616964757a686964616fe4b893e5b19e31333337613830 以sqlserver2008R2为例. 1.创 ...
- sql 只要一个字段相同则只显示一条数据_数据库
数据库:管理数据的仓库,其本质是一种数据结构. 一.数据 数据:即信息,包括视觉信息.听觉信息等等.当前数据库主要存储的是视觉信息(数字.文字等等) 二.数据库的组成 数据库是由一张张数据表组成的. ...
- mysql查出倒序第一条数据_[数据库]mysql 记录根据日期字段倒序输出
[数据库]mysql 记录根据日期字段倒序输出 0 2016-07-21 11:00:17 我们知道倒序输出是很简单的 select * from table order by id desc 直接这 ...
- mysql一张表1亿天数据_1亿条数据在PHP中实现Mysql数据库分表100张
转: 1亿条数据在PHP中实现Mysql数据库分表100张 http://php-z.com/thread-2115-1-1.html (出处: PHP-Z) 当数据量猛增的时候,大家都会选择库表散列 ...
最新文章
- OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...
- C技巧:结构体参数转成不定参数
- DeepMind的新强化学习系统是迈向通用AI的下一步吗?
- git(码云):如何把本地代码提交到码云代码管理项目上
- 基于区块链交易技术开发的证券
- bootcmd 和bootargs
- linux mysql安装教程 方大帝_discuz论坛出现Can not connect to MySQL server错误的解决方法...
- Java解决循环注入问题
- 17年第八届蓝桥杯省赛(C语言B组) 题解
- 7-8 评委打分 (5 分)
- Windows下Node.js安装Canvas插件
- 拿到offer怕查学历不敢去_《令人心动的offer》— 我们法庭见
- jar包运行utf-8格式
- 3D LUT调色预设如何导入并应用?(fcpx/PR/AE/PS/LR/达芬奇)
- 用Python转码恢复乱码中文
- 微信读书笔记-《采购与供应链管理》
- 代码评审的价值和规范
- android平台上持久化存储3种手段_Android--数据持久化之内部存储、Sdcard存储
- 李飞飞CS231n2017课程双语字幕版上线 !(附课程链接)
- 【归档】爬取马蜂窝景点信息(含源代码)
热门文章
- git 配置多个SSH-Key
- Android数据库 之 SQLite数据库
- 网络安全模型_基于TCM的网络安全访问模型
- 如何在vscode运行php代码_如何提高 PHP 代码的质量?
- java第5天_java第5天的代码
- 过滤一批数据_手把手教你学numpy,从此数据处理不再慌【三】
- prometheus连续查询_Prometheus查询
- element vue 动态单选_软件更新丨vue-element-admin 4.0.0 beta 发布,后台集成方案
- 计算机中职高考,中职计算机高考中的应用
- java双等号和equals_Java中的 equals和双等号,你懂吗?