目录
共享锁与排他锁
粒度锁
意向锁
悲观锁与乐观锁
死锁" >死锁
间隙锁" >间隙锁
MVCC 多版本并发控制" >MVCC 多版本并发控制
语句与锁" >语句与锁
首页 数据库 mysql教程 mysql第二天锁_MySQL

mysql第二天锁_MySQL

Jun 01, 2016 pm 12:59 PM

如果没有锁,那么并发性会更强,但是数据安全性会有问题。因此数据库会给数据加锁。

共享锁与排他锁

也就是读写锁,共享锁可以叠加共享锁但是不能加排他锁, 排他锁则不能叠加。
根据隔离级别等等,mysql会隐式的给数据自动加锁
此外还可以使用share in model, for update 等语句显示的加锁
登录后复制

粒度锁

粒度越细,维护锁的开销越大,并发性越高,数据越不安全。 通常有如下两种
- 行锁
只给一行数据加锁
- 表锁
给整张表加锁, 一般Alter table会使用表锁

意向锁

mysql为了提高冲突监测性能而存在的一种锁。是给其上一级所加的锁,所以在mysql中通常为表锁。
比如一个事务,给两行加了排他锁,又有一个事务想要给整个表加共享锁,这个时候就要去查看所有的表的行是否有锁策略不能加共享锁。 如果有了意向锁,那么事务1就能再给两行加排他锁的同时,给整个表加IX, 这样事务2不用遍历就能知道不可以加S锁了。

悲观锁与乐观锁

A,B两个人同时在系统上进行操作,比如要修改一份订单。 当A正在修改准备提交前向上厕所,这儿时候B修改完订单并且提交了。 这个时候A回来了再提交就会出现问题,B的修改被覆盖了。
- 悲观锁
for update, share in model语句
使用悲观锁,则会在操作期间全程对数据进行加锁,其他人不能再次修改。这样会造成比较长时间的阻塞。
适用于短事务,写量比较大的情况。
- 乐观锁
乐观锁通过在数据库中新增一个version字段,操作后给version + 1. 提交时比较,如果比数据库中的大,则提交。大概的代码是:

<code class="hljs scss">    if(connection.update("update set name=&#39;123&#39; where id=1 and version < #current_version#") > 0){
        // 表示更新成功了
    }</code>
登录后复制
<code class="hljs scss">这种适用于读多,写少,并且写有可能会用很长时间的情况。
</code>
登录后复制

死锁

比如有两个事物:<br /> 事物1

<code class="hljs scss"><code class="hljs sql">update table1 set name=&#39;1&#39; where id=1;
// sleep 1
update table1 set name=&#39;2&#39; where id=2;
commit;</code></code>
登录后复制

<code class="hljs sql">事物2

<code class="hljs scss"><code class="hljs sql"><code class="hljs sql">update table1 set name=&#39;2&#39; where id=2;
// sleep 2
update table1 set name=&#39;1&#39; where id=1;
commit;</code></code></code>
登录后复制

<code class="hljs sql"><code class="hljs sql">上面的语句如果恰巧一起执行到sleep1 和sleep2,那么就会造成死锁。 一般有三种做法解决:

<code class="hljs sql"><code class="hljs sql">一次锁所有数据 保持锁的顺序 允许死锁,然后kill掉代价最小的事务。回滚之

<code class="hljs sql"><code class="hljs sql">间隙锁

<code class="hljs scss"><code class="hljs sql"><code class="hljs sql">执行select .. from where id between这样的语句的时候锁定这一区间,不能插入或者删除数据,以防止幻读。
</code></code></code>
登录后复制

<code class="hljs sql"><code class="hljs sql">MVCC 多版本并发控制

<code class="hljs sql"><code class="hljs sql">mysql维护一个系统版本号,每次有新的事物开始的时候递增。<br /> 每行后面保存两个隐藏列。 一个创建时版本号C,一个删除时版本号D

<code class="hljs sql"><code class="hljs sql"><strong>INSERT</strong> 新增的行往C里写入当前系统版本号。 这样新事物可以通过这个版本号保证不查到他 <strong>DELETE</strong> 为删除的行写D字段为当前系统版本号。 <strong>UPDATE</strong> 插入一行新数据写C为当前系统版本号,老数据写D为当前系统版本号。 <strong>SELECT</strong> 的时候只查 C<=当前版本 && (D > 当前版本 || D is not defined) 这样主要是为了在不加锁的情况下,一个事务能够读取到事务开始前已经存在且未被删除,且没有经过修改的数据。 也就是解决脏读的问题。即该事物开始之后的其他事务的各种修改事务提交都不会对当前事务的读取产生影响。同时也解决了幻读的问题

<code class="hljs sql"><code class="hljs sql">语句与锁

<code class="hljs sql"><code class="hljs sql">InnoDB 的行锁是基于索引的,如果没有索引,或者不能使用索引则是表锁 select &hellip; from 一致性非阻塞读,不上锁。 select &hellip; from where lock in share mode 共享锁 select &hellip; from where &hellip; for update 排他锁 update .. where 排他锁 delete &hellip; from 排他锁<br /> 下面的例子来看锁的排他性<br /> 事务1
<code class="hljs scss"><code class="hljs sql"><code class="hljs sql"><code class="hljs sql"> set autocommit=0;
 begin;
 SELECT * FROM biz_pay_task where id = 1 FOR UPDATE;
 // wait
 commit;</code></code></code></code>
登录后复制

<code class="hljs sql"><code class="hljs sql"><code class="hljs sql">事务2

<code class="hljs scss"><code class="hljs sql"><code class="hljs sql"><code class="hljs sql"><code class="hljs sql"> set autocommit=0;
 begin;
 SELECT * FROM biz_pay_task where id = 1 LOCK IN SHARE MODE;
 commit;</code></code></code></code></code>
登录后复制

<code class="hljs sql"><code class="hljs sql"><code class="hljs sql">事务2在执行SELECT LOCK IN SHARE MODE的时候会阻塞,知道事务1commit之后才会完成。

 

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用Alter Table语句在MySQL中更改表? 如何使用Alter Table语句在MySQL中更改表? Mar 19, 2025 pm 03:51 PM

本文讨论了使用MySQL的Alter Table语句修改表,包括添加/删除列,重命名表/列以及更改列数据类型。

如何为MySQL连接配置SSL/TLS加密? 如何为MySQL连接配置SSL/TLS加密? Mar 18, 2025 pm 12:01 PM

文章讨论了为MySQL配置SSL/TLS加密,包括证书生成和验证。主要问题是使用自签名证书的安全含义。[角色计数:159]

您如何处理MySQL中的大型数据集? 您如何处理MySQL中的大型数据集? Mar 21, 2025 pm 12:15 PM

文章讨论了处理MySQL中大型数据集的策略,包括分区,碎片,索引和查询优化。

哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? 哪些流行的MySQL GUI工具(例如MySQL Workbench,PhpMyAdmin)是什么? Mar 21, 2025 pm 06:28 PM

文章讨论了流行的MySQL GUI工具,例如MySQL Workbench和PhpMyAdmin,比较了它们对初学者和高级用户的功能和适合性。[159个字符]

如何使用Drop Table语句将表放入MySQL中? 如何使用Drop Table语句将表放入MySQL中? Mar 19, 2025 pm 03:52 PM

本文讨论了使用Drop Table语句在MySQL中放下表,并强调了预防措施和风险。它强调,没有备份,该动作是不可逆转的,详细介绍了恢复方法和潜在的生产环境危害。

您如何用外国钥匙代表关系? 您如何用外国钥匙代表关系? Mar 19, 2025 pm 03:48 PM

文章讨论了使用外国密钥来代表数据库中的关系,重点是最佳实践,数据完整性和避免的常见陷阱。

如何在JSON列上创建索引? 如何在JSON列上创建索引? Mar 21, 2025 pm 12:13 PM

本文讨论了在PostgreSQL,MySQL和MongoDB等各个数据库中的JSON列上创建索引,以增强查询性能。它解释了索引特定的JSON路径的语法和好处,并列出了支持的数据库系统。

如何保护MySQL免受常见漏洞(SQL注入,蛮力攻击)? 如何保护MySQL免受常见漏洞(SQL注入,蛮力攻击)? Mar 18, 2025 pm 12:00 PM

文章讨论了使用准备好的语句,输入验证和强密码策略确保针对SQL注入和蛮力攻击的MySQL。(159个字符)

See all articles