搜尋
首頁資料庫mysql教程mysql第二天锁_MySQL

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

共享锁与排他锁

也就是读写锁,共享锁可以叠加共享锁但是不能加排他锁, 排他锁则不能叠加。
根据隔离级别等等,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 is not defined) 这样主要是为了在不加锁的情况下,一个事务能够读取到事务开始前已经存在且未被删除,且没有经过修改的数据。 也就是解决脏读的问题。即该事物开始之后的其他事务的各种修改事务提交都不会对当前事务的读取产生影响。同时也解决了幻读的问题

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

<code class="hljs sql"><code class="hljs sql">InnoDB 的行锁是基于索引的,如果没有索引,或者不能使用索引则是表锁 select … from 一致性非阻塞读,不上锁。 select … from where lock in share mode 共享锁 select … from where … for update 排他锁 update .. where 排他锁 delete … 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
MySQL和其他SQL方言之間的語法有什麼區別?MySQL和其他SQL方言之間的語法有什麼區別?Apr 27, 2025 am 12:26 AM

mysqldiffersfromothersqldialectsinsyntaxforlimit,自動啟動,弦樂範圍,子征服和表面上分析。 1)MySqluessLipslimit,whilesqlserverusestopopandoraclesrontersrontsrontsrontsronnum.2)

什麼是mysql分區?什麼是mysql分區?Apr 27, 2025 am 12:23 AM

MySQL分區能提升性能和簡化維護。 1)通過按特定標準(如日期範圍)將大表分成小塊,2)物理上將數據分成獨立文件,3)查詢時MySQL可專注於相關分區,4)查詢優化器可跳過不相關分區,5)選擇合適的分區策略並定期維護是關鍵。

您如何在MySQL中授予和撤銷特權?您如何在MySQL中授予和撤銷特權?Apr 27, 2025 am 12:21 AM

在MySQL中,如何授予和撤銷權限? 1.使用GRANT語句授予權限,如GRANTALLPRIVILEGESONdatabase_name.TO'username'@'host';2.使用REVOKE語句撤銷權限,如REVOKEALLPRIVILEGESONdatabase_name.FROM'username'@'host',確保及時溝通權限變更。

說明InnoDB和Myisam存儲引擎之間的差異。說明InnoDB和Myisam存儲引擎之間的差異。Apr 27, 2025 am 12:20 AM

InnoDB適合需要事務支持和高並發性的應用,MyISAM適合讀多寫少的應用。 1.InnoDB支持事務和行級鎖,適用於電商和銀行系統。 2.MyISAM提供快速讀取和索引,適合博客和內容管理系統。

MySQL中有哪些不同類型的連接?MySQL中有哪些不同類型的連接?Apr 27, 2025 am 12:13 AM

MySQL中有四種主要的JOIN類型:INNERJOIN、LEFTJOIN、RIGHTJOIN和FULLOUTERJOIN。 1.INNERJOIN返回兩個表中符合JOIN條件的所有行。 2.LEFTJOIN返回左表中的所有行,即使右表中沒有匹配的行。 3.RIGHTJOIN與LEFTJOIN相反,返回右表中的所有行。 4.FULLOUTERJOIN返回兩個表中所有符合或不符合JOIN條件的行。

MySQL中有哪些不同的存儲引擎?MySQL中有哪些不同的存儲引擎?Apr 26, 2025 am 12:27 AM

mysqloffersvariousStorageengines,每個suitedfordferentusecases:1)InnodBisidealForapplicationsNeedingingAcidComplianCeanDhighConcurncurnency,supportingtransactionsancions and foreignkeys.2)myisamisbestforread-Heavy-Heavywyworks,lackingtransactionsactionsacupport.3)記憶

MySQL中有哪些常見的安全漏洞?MySQL中有哪些常見的安全漏洞?Apr 26, 2025 am 12:27 AM

MySQL中常見的安全漏洞包括SQL注入、弱密碼、權限配置不當和未更新的軟件。 1.SQL注入可以通過使用預處理語句防止。 2.弱密碼可以通過強制使用強密碼策略避免。 3.權限配置不當可以通過定期審查和調整用戶權限解決。 4.未更新的軟件可以通過定期檢查和更新MySQL版本來修補。

您如何確定MySQL中的慢速查詢?您如何確定MySQL中的慢速查詢?Apr 26, 2025 am 12:15 AM

在MySQL中識別慢查詢可以通過啟用慢查詢日誌並設置閾值來實現。 1.啟用慢查詢日誌並設置閾值。 2.查看和分析慢查詢日誌文件,使用工具如mysqldumpslow或pt-query-digest進行深入分析。 3.優化慢查詢可以通過索引優化、查詢重寫和避免使用SELECT*來實現。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!