mysql:如何解決資料修改衝突(事務+行級鎖的實際運用)

itread01 2021-01-21 20:05:30
Mysql 数据库/缓存 itread01 何解 修改


摘要:最近做一個接診需求遇到一個問題,假設一個訂單諮詢超過3次就不能再接診,但如果兩個醫生同時對該訂單進行諮詢,查資料庫的時候都能查到滿足條件的該訂單,那兩個醫生都能接診,所謂接診可以理解為更新了接診次數,此時就出現了bug(接診超過3次)。

其實這個問題看似很明朗,但想要完全解決需要理解事務和鎖的概念,以前總對事務的隔離級別和鎖有點雲裡霧裡,現在可以通過這個案例可以理清楚。

事務

操作資料庫最小的工作單位,簡單講就是將多條dml(增刪改)語句聯合完成。要麼同時成功,要麼同時失敗。看到這裡你可能會發現光加事務解決不了上述問題,而且加了事務之後,多條事務之間的相互關係就涉及到事務的隔離級別,所以接著往下看。

事務隔離級別

READ UNCOMMITTED(讀未提交,髒讀)

事務中的修改,即使沒有提交,對其他會話也是可見的。可以讀取未提交的資料——髒讀。髒讀會導致很多問題,一般不適用這個隔離級別.。

 

-- ------------------------- read-uncommitted例項 -------------------------------- 設定全域性系統隔離級別SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;-- Session ASTART TRANSACTION;SELECT * FROM USER;UPDATE USER SET NAME="READ UNCOMMITTED";-- commit;-- Session BSELECT * FROM USER;//SessionB Console 可以看到Session A未提交的事物處理,在另一個Session 中也看到了,這就是所謂的髒讀id name2 READ UNCOMMITTED34 READ UNCOMMITTED

 

READ COMMITTED(讀已提交,不可重複讀)

一般資料庫都預設使用這個隔離級別(MySQL 不是), 這個隔離級別保證了一個事務如果沒有完全成功(commit 執行完),事務中的操作對其他會話是不可見的。

-- ------------------------- read-cmmitted例項 -------------------------------- 設定全域性系統隔離級別SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;-- Session ASTART TRANSACTION;SELECT * FROM USER;UPDATE USER SET NAME="READ COMMITTED";-- COMMIT;-- Session BSELECT * FROM USER;//Console OUTPUT:id name2 READ UNCOMMITTED34 READ UNCOMMITTED----------------------------------------------------- 當 Session A執行了commit,Session B得到如下結果:id name2 READ COMMITTED34 READ COMMITTED

REPEATABLE READ (可重複讀)

一個事務中多次執行統一讀 SQL,返回結果一樣。這個隔離級別解決了髒讀的問題,幻讀問題。這裡指的是 innodb 的 rr 級別,innodb 中使用 next-key 鎖對"當前讀"進行加鎖,鎖住行以及可能產生幻讀的插入位置,阻止新的資料插入產生幻行。

會話T1事務中執行一次查詢,然後會話T2新插入一行記錄,這行記錄恰好可以滿足T1所使用的查詢的條件。然後T1又使用相同 的查詢再次對錶進行檢索,但是此時卻看到了事務T2剛才插入的新行。這個新行就稱為“幻像”,因為對T1來說這一行就像突然 出現的一樣。innoDB 的 RR 級別無法做到完全避免幻讀。

SERIALIZABLE (可序列化)

最強的隔離級別,通過給事務中每次讀取的行加鎖,寫加寫鎖,保證不產生幻讀問題,但是會導致大量超時以及鎖爭用問題。

mysql預設的隔離級別是可重複讀,看到這裡大家應該明白,即使隔離級別是可重複讀,但因為select操作時並未加鎖,導致都會查到符合條件的資料,所以這裡要引入一個鎖的概念:行級鎖。

行級鎖

  • 共享鎖(S) 共享鎖也稱為讀鎖,讀鎖允許多個連線可以同一時刻併發的讀取同一資源,互不干擾;

  • 排他鎖(X) 排他鎖也稱為寫鎖,一個寫鎖會阻塞其他的寫鎖或讀鎖,保證同一時刻只有一個連線可以寫入資料,同時防止其他使用者對這個資料的讀寫。

總結(解決方案)

其實上文分析了那麼多,最後的解決方案很簡單。就是在原來的read和update合起來加事務,原來的select語句加排他鎖,即在select語句後面加for update。假如有事務A,B,加入排他鎖之後,假設事務A先獲得鎖,事務B必須等到事務A commit之後才能開始select,所以讀到的是最新修改的資料。至於為什麼不加共享鎖,除了可能造成髒寫之後,在這種情況下還可能造成死鎖。假如兩個事務 A 、 B 都讀取同一行記錄,那麼在這一行就加上了共享鎖,但是 A 和B 事務中都需要修改這一行,那麼都要等待對方釋放共享鎖才能進行,結果造成了死鎖。

&n

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1611227466.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云