1. 程式人生 > >Mysql 中select for update 的幾種情況

Mysql 中select for update 的幾種情況

悲觀鎖是對資料被的修改持悲觀態度(認為資料在被修改的時候一定會存在併發問題),因此在整個資料處理過程中將資料鎖定。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在應用層中實現了加鎖機制,也無法保證外部系統不會修改資料)。

使用場景舉例

  商品goods表中有一個欄位status,status為1代表商品未被下單,status為2代表商品已經被下單,那麼我們對某個商品下單時必須確保該商品status為1。假設商品的id為1。如果不採用鎖,那麼操作方法如下:

1 2 3 4 5 6 //1.查詢出商品資訊 select  status  from  t_goods  where  id=1; //2.根據商品資訊生成訂單 insert  into  t_orders (id,goods_id) values (
null ,1); //3.修改商品status為2 update t_goods  set  status=2;

  上面這種場景在高併發訪問的情況下很可能會出現問題。前面已經提到,只有當goods status為1時才能對該商品下單,上面第一步操作中,查詢出來的商品status為1。但是當我們執行第三步Update操作的時候,有可能出現其他人先一步對商品下單把goods status修改為2了,但是我們並不知道資料已經被修改了,這樣就可能造成同一個商品被下單2次,使得資料不一致。所以說這種方式是不安全的。

使用悲觀鎖來實現

  在上面的場景中,商品資訊從查詢出來到修改,中間有一個處理訂單的過程,使用悲觀鎖的原理就是,當我們在查詢出goods資訊後就把當前的資料鎖定,直到我們修改完畢後再解鎖。那麼在這個過程中,因為goods被鎖定了,就不會出現有第三者來對其進行修改了。要使用悲觀鎖,我們必須關閉mysql資料庫的自動提交屬性。

1 2 3 4 5 6 7 8 9 10 11 12 set  autocommit=0;   //設定完autocommit後,我們就可以執行我們的正常業務了。具體如下: //0.開始事務 begin;/begin work;/start transaction; (三者選一就可以) //1.查詢出商品資訊 select  status  from  t_goods  where  id=1  for  update; //2.根據商品資訊生成訂單 insert  into  t_orders (id,goods_id) values ( null ,1); //3.修改商品status為2 update t_goods  set  status=2; //4.提交事務 commit;/commit work;

  注:上面的begin/commit為事務的開始和結束,因為在前一步我們關閉了mysql的autocommit,所以需要手動控制事務的提交,在這裡就不細表了。

  上面的第一步我們執行了一次查詢操作:select status from t_goods where id=1 for update;與普通查詢不一樣的是,我們使用了select…for update的方式,這樣就通過資料庫實現了悲觀鎖。此時在t_goods表中,id為1的那條資料就被我們鎖定了,其它的事務必須等本次事務提交之後才能執行。這樣我們可以保證當前的資料不會被其它事務修改。

  注:需要注意的是,在事務中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 相同資料時會等待其它事務結束後才執行,一般SELECT ... 則不受此影響。拿上面的例項來說,當我執行select status from t_goods where id=1 for update;後。我在另外的事務中如果再次執行select status from t_goods where id=1 for update;則第二個事務會一直等待第一個事務的提交,此時第二個查詢處於阻塞的狀態,但是如果我是在第二個事務中執行select status from t_goods where id=1;則能正常查詢出資料,不會受第一個事務的影響。

補充:MySQL select…for update的Row Lock與Table Lock

  上面我們提到,使用select…for update會把資料給鎖住,不過我們需要注意一些鎖的級別,MySQL InnoDB預設Row-Level Lock,所以只有「明確」地指定主鍵,MySQL 才會執行Row lock (只鎖住被選取的資料) ,否則MySQL 將會執行Table Lock (將整個資料表單給鎖住)。

舉例說明:

  資料庫表t_goods,包括id,status,name三個欄位,id為主鍵,資料庫中記錄如下;

 

  注:為了測試資料庫鎖,我使用兩個console來模擬不同的事務操作,分別用console1、console2來表示。

例1: (明確指定主鍵,並且有此資料,row lock)

  console1:查詢出結果,但是把該條資料鎖定了

1 2 set  autocommit=0; SELECT *  from  t_goods  where  id=1  for  update;

 

  console2:查詢被阻塞

  console2:如果console1長時間未提交,則會報錯

例2: (明確指定主鍵,若查無此資料,無lock)

  console1:查詢結果為空

1 2 set  autocommit=0; SELECT *  from  t_goods  where  id=4  for  update;

  console2:查詢結果為空,查詢無阻塞,說明console1沒有對資料執行鎖定

1 2 set  autocommit=0; SELECT *  from  t_goods  where  id=4  for  update;

例3: (無主鍵,table lock)

  console1:

1 2 set  autocommit=0; SELECT *  from  t_goods  where  status=1  for  update;

  console2:

1

相關推薦

Mysql select for update情況

悲觀鎖是對資料被的修改持悲觀態度(認為資料在被修改的時候一定會存在併發問題),因此在整個資料處理過程中將資料鎖定。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在應用層中實現了加鎖機制,也無法保證外部系統不會修改資料)。 使用場景舉例

數據庫:Mysqlselect ... for update”排他鎖分析

nbsp 檢索 語句 mit AI pda 兩種 訪問 upd Mysql InnoDB 排他鎖 用法: select … for update; 例如:select * from goods where id = 1 for update; 排他鎖的申

MySql資料庫MySQLselect * for update鎖表的問題

       由於InnoDB預設是Row-Level Lock,所以只有「明確」的指定主鍵,MySQL才會執行Row lock (只鎖住被選取的資料例) ,否則MySQL將會執行Table Lock (將整個資料表單給鎖住)。 舉個例子: 假設有個表單p

MySQLselect * for update鎖表的範圍

MySQL中select * for update鎖表的問題 由於InnoDB預設是Row-Level Lock,所以只有「明確」的指定主鍵,MySQL才會執行Row lock (只鎖住被選取的資料例) ,否則MySQL將會執行Table Lock (將整個資料表單給鎖住)。 舉個例子: 假設有個表單p

資料庫:Mysqlselect ... for update”排他鎖分析

Mysql InnoDB 排他鎖 用法: select … for update; 例如:select * from goods where id = 1 for update; 排他鎖的申請前提:沒有執行緒對該結果集中的任何行資料使用排他鎖或共享鎖,否則

Mysql索引會失效的情況分析

status 過程 ges 此外 ont 其中 like hand ext 轉自:http://www.jb51.net/article/50649.htm 在做項目的過程中,難免會遇到明明給mysql建立了索引,可是查詢還是很緩慢的情況出現,下面我們來具體分析下這種

【數據庫】Mysql主鍵的表設計組合的實際應用效果

研究 開始時間 action 設計 int rand 業務主鍵 primary 同時 寫在前面 前前後後忙忙碌碌,度過了新工作的三個月。博客許久未新,似乎對忙碌沒有一點點防備。總結下來三個月不斷的磨礪自己,努力從獨樂樂轉變到眾樂樂,體會到不一樣的是,連辦公

HTML呼叫JavaScript的情況和規範寫法

JavaScript執行在html中,引用有幾種方式? 我知道的方法有3種: 第一種:外部引用遠端JavaScript檔案。如<script type="text/javascript" src="../js/jquery-1.8.3.js"></script>(相對

神仙打架?細數玩刺激戰場被檢測的情況:你招了嗎?

玩刺激戰場被封號了怎麼辦?不少人玩刺激戰場的時候會跳出各種彈框,基本分為幾種:模擬器玩家、模擬器過檢測玩家、WG玩家,還有人在問為什麼會別檢測甚至封號,講真的,什麼原因你心裡沒點13數嗎?一起來看看各種遊戲彈窗代表的含義吧。 1、提示:檢測到您使用模擬器登入遊戲,匹配模擬器玩家  

【資料庫】Mysql主鍵的表設計組合的實際應用效果

寫在前面         前前後後忙忙碌碌,度過了新工作的三個月。部落格許久未新,似乎對忙碌沒有一點點防備。總結下來三個月不斷的磨礪自己,努力從獨樂樂轉變到眾樂樂,體會到不一樣的是,連辦公室的新玩意都能引起莫名的興趣了,作為一隻忙碌的 “猿” 倒不知正常與否。         咳咳, 正題, 今天要寫一篇

Mysql字串處理的處理方法concat、concat_ws、group_concat

Mysql中字串處理的幾種處理方法concat、concat_ws、group_concat以下詳情:   1.MySQL中concat函式 使用方法: CONCAT(str1,str2,…)     返回結果為連線引數產生的字串。

資料庫Select For update語句的解析

——————————— Oracle —————————————————– Oracle 的for update行鎖 鍵字: oracle 的for update行鎖   SELECT…FOR UPDATE 語句的語法如下:   SELECT …

ORACLE更新資料,PLSQL DeveloperSELECT ... FOR UPDATESELECT T.*,ROWID的區別

背景:ORACLE中更新少量資料時,在PLSQL  Developer中,一般用的語句是SELECT   FOR   UPDATE和SELECT   T.*,ROWID,這倆語句執行之後可以手動在查詢出來的資料中修改。例項背景:表名A,資料如下:  ACOL1    COL2

Android記憶體洩漏的情況

1.單例造成的記憶體洩漏; Android中單例模式中的餓漢式寫法如下: public class Example  { private static Example Instance; private Example(Context context) { this.con

今天來給大家分析jsthis的指向情況

        之前在寫程式碼時遇到this時,總是在考慮應不應該用,原因是當時分不清楚,後來把this的所有情況分析了一遍,其實超級簡單,而且他的使用場景很好,下面我來把他的幾種情況分析一下,如果this分佈太清得小夥伴們可以參考哈~希望對你們有幫助!        與其他

MYSQL建立外來鍵失敗情況記錄Can't create table不能建立表

像這種不能建立一個.frm 檔案的報錯好像暗示著作業系統的檔案的許可權錯誤或者其它原因,但實際上,這些都不是的,事實上,這個mysql報錯已經被報告是一個mysql本身的bug並出現在mysql 開發者列表當中很多年了,然而這似乎又是一種誤導。 在很多例項中,這種錯誤的發生都是因為mysql一直以來都不能很

DB2個隔離級別select..for update with ** 的行鎖

最近專案中遇到了多執行緒高併發專案db2資料庫表死鎖的情況,蒐集了一些關於表死鎖的資料 Create table RRTest (pkID VARCHAR(20) NOT NULL ,unID1&nb

【轉載】MySQL事務以及SELECT ... FOR UPDATE的使用

商品 tail ase -a base 我們 evel erl tel MySQL中的事務,默認是自動提交的,即autocommit = 1; 但是這樣的話,在某些情形中就會出現問題:比如: 如果你想一次性插入了1000條數據,mysql會commit1000次的, 如果我

[轉]DB2需要REORG操作的情況

sting line lte font -type compress win rmi col 問題: 在DB2數據庫中,修改完表的結構時,是否需要對表做一個reorg操作才能使表的狀態恢復正常? 答:有以下4種操作,需要對表做reorg操作 1. SET DATA TYPE

Mysql加鎖過程詳解(4)-select for update/lock in share mode 對事務並發性影響

per inno targe 允許 evel transacti 修改 not null warn select for update/lock in share mode 對事務並發性影響 事務並發性理解 事務並發性,粗略的理解就是單位時間內能夠執行的事務數量,常見的單