首頁 資料庫 mysql教程 MySQL中的事務與鎖

MySQL中的事務與鎖

Feb 06, 2017 am 11:12 AM

這篇文章詳細介紹資料庫事務與鎖的相關知識。主要是一些概念性的東西看起來可能比較乏味,但作為一個合格的程式設計師來說,你應該掌握也必須掌握。這些理論知識好比是一個人的內功,我們平常敲程式碼是外功,只有內外兼修,互相促進,才能達到武林高手的境界。好了廢話不多說,從下面開始。

資料庫事務

事務的邊界

事務的開始邊界(begin) 
事務的結束邊界(commit):提交事務,永久保存被事務更新後的資料庫狀態。 
事務的異常結束邊界(rollback):撤銷事務,使資料庫退回到執行事務前的初始狀態。

每啟動一個MySQL.exe程序,就會得到一個單獨的資料庫連線。每個資料庫連線都有一個全域變數autocommit,表示目前的交易模式,它有兩個值可選:

  • 0:表示手動提交模式

  • 1:表示自動提交模式,預設值

1:表示自動提交模式,預設值

我們可以查看和修改這個值。
  • 資料庫事務的4個特性(ACID):

  • 原子性(Atomicity):事務是一個原子操作單元,其對資料的修改,要麼全部執行,要麼全都不一致;

  • 性(Consistent):在事務開始和完成時,資料都必須保持一致狀態;
  • 隔離性(Isolation):資料庫系統提供一定的隔離機制,保證事務在不受外部並發操作影響的“獨立”環境執行;

持久性(Durable):事務完成之後,它對於資料的修改是永久性的,即使出現系統故障也能夠維持。

MySQL中的事務與鎖

事務隔離級別
  • 資料庫事務隔離級別,只是針對一個事務能不能讀取其它事務的中間結果。



  • Read Uncommitted (讀取未提交內容) 

    在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離等級很少用於實際應用,因為它的效能也不比其他等級好多少。讀取未提交的數據,也稱為髒讀( Dirty Read )。 🎜🎜🎜🎜Read Committed (讀取提交內容) 🎜這是大多數資料庫系統的預設隔離等級(但不是 MySQL 預設的)。它滿足了隔離的簡單定義:一個交易只能看見已經提交事務所所做的改變。這種隔離等級 也支援所謂的不可重複讀取( Nonrepeatable Read ),因為同一交易的其他實例在該實例處理其間可能會有新的 commit ,所以同一 select 可能會傳回不同結果。 🎜
  • Repeatable Read (可重讀) 
    這是 MySQL 的預設事務隔離級別,它確保相同交易的多個實例在並發讀取資料時,會看到相同的資料行。不過理論上,這會導致另一個棘手的問題:幻讀 ( Phantom Read )。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,另一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的”幻影” 行。 InnoDB和 Falcon 儲存引擎透過多版本並發控制( MVCC , Multiversion Concurrency Control )機制解決了這個問題。

  • Serializable (可串行化) 
    這是最高的隔離級別,它透過強制事務排序,使其不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀取的資料行上加上共享鎖定。在這個級別,可能導致大量的超時現象和鎖定競爭。

隔離等級越高,越能保證資料的完整性和一致性,但對並發效能的影響也越大。 
對於多數應用程序,可以有效考慮把資料庫系統的隔離等級設為Read Committed,它能夠避免髒讀,而且具有較好的並發性能。儘管它會導致不可重複讀、虛度和第二類丟失更新這些並發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖和樂觀鎖來控制。

事務的傳播性

  1. PROPAGATION_REQUIRED 
    加入當前正要執行的事務,如果當前事務不存在,那麼就起一個新的事務。 Spring 操作資料庫預設的交易傳播行為就是 propagation_required 。

  2. PROPAGATION_SUPPORTS 
    如果目前在事務中,即以事務的形式運行,如果當前不再一個事務中,那麼就以非事務的形式運行.

  3. PROPAGATION_MANDATORY_MANDATORY也就是說,他只能被一個父事務呼叫。否則,他就要拋出異常。

  4. PROPAGATION_REQUIRES_NEW 

    掛起目前事務,另一個新的交易。

  5. PROPAGATION_NOT_SUPPORTED 

    目前不支援交易。如果在事務中,會掛起目前事務,自己以非事務的行為運作。

  6. PROPAGATION_NEVER 

    不能在事務中運行,如果在事務中運行就會拋出異常。

  7. PROPAGATION_NESTED 

    嵌套的事務依賴父事務,父事務提交,它跟著提交,父事務回滾,它跟著回滾。

行級鎖定

Mysql中三種類型的鎖定:

行級:引擎 INNODB , 單獨的一行記錄加鎖 

頁級:引擎 BDB,一次鎖定相鄰的一組記錄。 
表級:引擎 MyISAM , 理解為鎖住整個表,可以同時讀,寫不行。 
三種鎖的特性大致可歸納如下: 
1) 表級鎖定:開銷小,加鎖快;不會出現死鎖;鎖定粒徑大,發生鎖衝突的機率最高,且發度最低。 
2) 行級鎖定:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖定衝突的機率最低,並發度也最高。 
3) 頁面鎖定:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。

我們這裡主要談論的是行級鎖,一般的在秒殺系統中我們會對商品庫存使用行級鎖,因為秒殺的時候庫存是一個很重要的數據,我們在創建數據庫的表時可能會出現下面這樣的設定:

ENGINE = InnoDB AUTO_INCREMENT=10 DEFAULT CHARACTER SET = utf8 comment='用户表
登入後複製

將引擎設定為InnoDB,InnnoDB與其他引擎的不同:一是支援事務(TRANCSACTION),二是採用了行級鎖定。

InnoDB中两种模式的行级锁:

1)共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
( Select * from table_name where ……lock in share mode)
2)排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和 排他写锁。(select * from table_name where…..for update)

为了允许行锁和表锁共存,实现多粒度锁机制;同时还有两种内部使用的意向锁(都是表锁),分别为意向共享锁和意向排他锁。

  • 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。

  • 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。

注意:InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的。InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

行级锁的优缺点

行级锁定的优点:

  • 当在许多线程中访问不同的行时只存在少量锁定冲突。

  • 回滚时只有少量的更改。

  • 可以长时间锁定单一的行。

行级锁定的缺点:

  • 比页级或表级锁定占用更多的内存。

  • 当在表的大部分数据上使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。如果你在大部分数据上经常进行GROUP BY操作或

者必须经常扫描整个表,比其它锁定明显慢很多。

hibernate中通过行级锁实现的悲观锁。

一些例子:

假设有个表单products ,里面有id跟name二个栏位,id是主键。
1: 明确指定主键,并且有此条记录,执行row lock。若查无此记录,无lock。

SELECT * FROM products WHERE id='3' FOR UPDATE;SELECT * FROM products WHERE id='3' and name="cat" FOR UPDATE;
登入後複製

2: 无主键,执行table lock。

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
登入後複製

3: 主键不明确,table lock。

SELECT * FROM products WHERE id<>&#39;3&#39; FOR UPDATE;
登入後複製

注意: FOR UPDATE仅适用于InnoDB,且必须在事务块(BEGIN/COMMIT)中才能生效。此外,如果A与B都对表id进行查询但查询不到记录,则A与B在查询上不会进行row锁,但A与B都会获取排它锁,此时A再插入一条记录的话则会因为B已经有锁而处于等待中,此时B再插入一条同样的数据则会抛出Deadlock found when trying to get lock; try restarting transaction。然后释放锁,此时A就获得了锁而插入成功。

以上就是MySQL中的事务与锁的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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脫衣器

Video Face Swap

Video Face Swap

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

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 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)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1253
24
MySQL的角色:Web應用程序中的數據庫 MySQL的角色:Web應用程序中的數據庫 Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

說明InnoDB重做日誌和撤消日誌的作用。 說明InnoDB重做日誌和撤消日誌的作用。 Apr 15, 2025 am 12:16 AM

InnoDB使用redologs和undologs確保數據一致性和可靠性。 1.redologs記錄數據頁修改,確保崩潰恢復和事務持久性。 2.undologs記錄數據原始值,支持事務回滾和MVCC。

MySQL的位置:數據庫和編程 MySQL的位置:數據庫和編程 Apr 13, 2025 am 12:18 AM

MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

MySQL與其他編程語言:一種比較 MySQL與其他編程語言:一種比較 Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

MySQL:從小型企業到大型企業 MySQL:從小型企業到大型企業 Apr 13, 2025 am 12:17 AM

MySQL適合小型和大型企業。 1)小型企業可使用MySQL進行基本數據管理,如存儲客戶信息。 2)大型企業可利用MySQL處理海量數據和復雜業務邏輯,優化查詢性能和事務處理。

MySQL索引基數如何影響查詢性能? MySQL索引基數如何影響查詢性能? Apr 14, 2025 am 12:18 AM

MySQL索引基数对查询性能有显著影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

初學者的MySQL:開始數據庫管理 初學者的MySQL:開始數據庫管理 Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括創建數據庫、表格,及使用SQL進行數據的CRUD操作。 1.創建數據庫:CREATEDATABASEmy_first_db;2.創建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入數據:INSERTINTObooks(title,author,published_year)VA

MySQL與其他數據庫:比較選項 MySQL與其他數據庫:比較選項 Apr 15, 2025 am 12:08 AM

MySQL適合Web應用和內容管理系統,因其開源、高性能和易用性而受歡迎。 1)與PostgreSQL相比,MySQL在簡單查詢和高並發讀操作上表現更好。 2)相較Oracle,MySQL因開源和低成本更受中小企業青睞。 3)對比MicrosoftSQLServer,MySQL更適合跨平台應用。 4)與MongoDB不同,MySQL更適用於結構化數據和事務處理。

See all articles