【資料庫】MySQL進階四、select

2021-03-02 Java幫幫
mysql中select * for update註:

 FOR UPDATE 僅適用於InnoDB,且必須在事務區塊(BEGIN/COMMIT)中才能生效。

作用

鎖定該語句所選擇到的對象。防止在選擇之後別的地方修改這些對象造成數據不一致。要保證在統計(查詢)執行過程中,記錄不被其他用戶更新,

則可以使用For update子句進行加鎖。這樣在這個鎖釋放前其他用戶不能對這些記錄作update、delete和加鎖。

Select   daptno   from    dept Where   deptno=25   For update;
如果你使用了FOR UPDATE來對表進行加鎖,則必須用commit來釋放加鎖的記錄。

	鎖分成兩類:加鎖範圍子句和加鎖行為子句	加鎖範圍子句:	在select…for update之後,可以使用of子句選擇對select的特定數據表進行加鎖操作。默認情況下,不使用of子句表示在select所有的數據表中加鎖	加鎖行為子句:	當我們進行for update的操作時,與普通select存在很大不同。一般select是不需要考慮數據是否被鎖定,最多根據多版本一致讀的特性讀取之前的版本。

規則	for UPDATE語句將鎖住查詢結果中的元組,這些元組將不能被其他事務的UPDATE,delete和for UPDATE操作,直到本事務提交。


應用場景
	那麼,什麼時候需要使用for update?就是那些需要業務層面數據獨佔時,可以考慮使用for update。場景上,比如火車票訂票,在屏幕上顯示餘票,而真正進行出票時,需要重新確定一下這個數據沒有被其他客戶端修改。所以,在這個確認過程中,可以使用for update。這是統一的解決方案方案問題,需要前期有所準備。

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


舉例1

給你舉幾個例子:
select * from t for update 會等待行鎖釋放之後,返回查詢結果。
select * from t for update nowait 不等待行鎖釋放,提示鎖衝突,不返回結果
select * from t for update wait 5 等待5秒,若行鎖仍未釋放,則提示鎖衝突,不返回結果
select * from t for update skip locked 查詢返回查詢結果,但忽略有行鎖的記錄 

SELECT...FOR UPDATE 語句的語法如下: 
  SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED]; 
其中: 
  OF 子句用於指定即將更新的列,即鎖定行上的特定列。 
  WAIT 子句指定等待其他用戶釋放鎖的秒數,防止無限期的等待。

「使用FOR UPDATE WAIT」子句的優點如下: 
  1防止無限期地等待被鎖定的行; 
  2允許應用程式中對鎖的等待時間進行更多的控制。 
  3對於交互式應用程式非常有用,因為這些用戶不能等待不確定 
  4 若使用了skip locked,則可以越過鎖定的行,不會報告由wait n 引發的『資源忙』異常報告


舉例2

假設有個表單products ,裡面有id跟name二個欄位,id是主鍵。

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

SELECT * FROM products WHERE id='3' FOR UPDATE;

SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;

 

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

SELECT * FROM products WHERE id='-1' FOR UPDATE;

 

例2: (無主鍵,table lock)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

 

例3: (主鍵不明確,table lock)

SELECT * FROM products WHERE id<>'3' FOR UPDATE;

 

例4: (主鍵不明確,table lock)

SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

 

注1: FOR UPDATE僅適用於InnoDB,且必須在交易區塊(BEGIN/COMMIT)中才能生效。

注2: 要測試鎖定的狀況,可以利用MySQL的Command Mode ,開二個視窗來做測試。

 

在MySql 5.0中測試確實是這樣的。

另外:MyAsim 只支持表級鎖,InnerDB支持行級鎖。

添加了(行級鎖/表級鎖)鎖的數據不能被其它事務再鎖定,也不被其它事務修改(修改、刪除)是表級鎖時,不管是否查詢到記錄,都會鎖定表。

此外,如果A與B都對表id進行查詢但查詢不到記錄,則A與B在查詢上不會進行row鎖,但A與B都會獲取排它鎖,此時A再插入一條記錄的話則會因為B已經有鎖而處於等待中,此時B再插入一條同樣的數據則會拋出Deadlock found when trying to get lock; try restarting transaction然後釋放鎖,此時A就獲得了鎖而插入成功。


知識補充

鎖是資料庫中的一個非常重要的概念,它主要用於多用戶環境下保證資料庫完整性和一致性。 我們知道,多個用戶能夠同時操縱同一個資料庫中的數據,會發生數據不一致現象。即如果沒有鎖定且多個用戶同時訪問一個資料庫,則當他們的事務同時使用相同的數據時可能會發生問題。這些問題包括:丟失更新、髒讀、不可重複讀和幻覺讀:


1.當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最後的更新將重寫由其它事務所做的更新,這將導致數據丟失。例如,兩個編輯人員製作了同一文檔的電子複本。每個編輯人員獨立地更改其複本,然後保存更改後的複本,這樣就覆蓋了原始文檔。最後保存其更改複本的編輯人員覆蓋了第一個編輯人員所做的更改。如果在第一個編輯人員完成之後第二個編輯人員才能進行更改,則可以避免該問題。


2. 髒讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到資料庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。因為這個數據是還沒有提交的數據,那麼另外一個事務讀到的這個數據是髒數據,依據髒數據所做的操作可能是不正確的。例如,一個編輯人員正在更改電子文檔。在更改過程中,另一個編輯人員複製了該文檔(該複本包含到目前為止所做的全部更改)並將其分發給預期的用戶。此後,第一個編輯人員認為目前所做的更改是錯誤的,於是刪除了所做的編輯並保存了文檔。分發給用戶的文檔包含不再存在的編輯內容,並且這些編輯內容應認為從未存在過。如果在第一個編輯人員確定最終更改前任何人都不能讀取更改的文檔,則可以避免該問題。


3.不可重複讀是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那麼,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麼第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重複讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重複。如果只有在作者全部完成編寫後編輯人員才可以讀取文檔,則可以避免該問題。

 
4.幻覺讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合併到該文檔的主複本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。


      所以,處理多用戶並發訪問的方法是加鎖。鎖是防止其他事務訪問指定的資源控制、實現並發控制的一種主要手段。當一個用戶鎖住資料庫中的某個對象時,其他用戶就不能再訪問該對象。加鎖對並發訪問的影響體現在鎖的粒度上。為了控制鎖定的資源,應該首先了解系統的空間管理。

相關焦點

  • mysql資料庫select查詢語句
    select的相關語句在mysql中用的非常多,介紹一下。select語句的介紹1 select * from 表名;*(代表表中的所有欄位)2 select distinct 欄位名 from* from 表名 limit 0,3;從第一條開始 找三條數據7 聚合函數sum 函數 select sum(欄位名) from 表名; 求某個欄位的和avg 函數 select avg(欄位名) from 表名; 求某個欄位的平均值
  • MySQL資料庫測試題
    >資料庫中,以下哪條語句是取第2頁中的數據?* from test limit 10,20;D、select * from test limit 11,20;2在Mysql資料庫中,以下哪條語句用於統計test表中的記錄總數
  • 考前複習必備MySQL資料庫(關係型資料庫管理系統)
    mysql資料庫管理資料庫進行初始化初始化資料庫,在安裝好mysql資料庫後,不要直接啟動,需要對資料庫進行初始化。grant select, insert on mysql.test TO 'test1'@'%';表示授權用戶test1在所有登錄主機均對mysql庫的test表擁有select和insert權限。
  • python對mysql資料庫的操作(一)
    python操作mysql會使用到很多的方法,具體總結經常使用的,見如下的:connect():連接mysql 的資料庫commit():提交rollback():回滾fetchone():返回一條語句fetchall():返回所有語句fetchmany():返回多條數據close():關閉資料庫
  • 將mysql數據導入access資料庫
    首頁 > 語言 > 關鍵詞 > 最新資訊 > 正文 將mysql數據導入access資料庫
  • 揭秘一條select語句,在MySQL中權限訪問控制內幕
    第一:用戶管理模塊第二:用戶訪問動作控制模塊,用戶訪問動作最常見就是DML,DDL其中用戶管理模塊的作用,就是驗證用戶能否合法登錄mysql資料庫,而用戶訪問動作控制模塊,則控制這合法用戶能做動作。其實這麼說還是有些抽象,那來看看mysql資料庫中關於權限訪問控制的4張表。
  • 一看就會,MySQL資料庫的基本操作(四)
    打開命令:net start mysql;關閉命令:net stop mysql打開、關閉資料庫命令2、登陸資料庫命令:mysql -h 主機地址 -u 用戶名 -p 用戶密碼。退出命令:exit登陸、退出資料庫命令3、添加資料庫用戶的操作:比如添加一個用戶有查詢、插入、修改、刪除的權限,那麼命令是:grant select,insert
  • 玩轉Mysql系列 - 第6篇:select查詢基礎篇
    環境:mysql5.7.25,cmd命令中進行演示。DQL(Data QueryLanguage):數據查詢語言,通俗點講就是從資料庫獲取數據的,按照DQL的語法給資料庫發送一條指令,資料庫將按需求返回數據。DQL分多篇來說,本文屬於第1篇。
  • MySQL 優化案例 - select count-愛可生
    mysql> explain select count(*) from api_runtime_log \G;*************************** 1. row *************************** id: 1 select_type: SIMPLE table: api_runtime_log partitions
  • 了解資料庫類型及MySQL資料庫常用命令行
    一、資料庫1、資料庫DataBase(DB):存儲數據的倉庫。2、資料庫的分類(1) 關係型資料庫(sql資料庫):中型:mysql(埠號3306)、sql server大型:Oracle(埠號1521)(2) 非關係型資料庫(no-sql資料庫)
  • mysql中使用select的正確姿勢
    你們上班可以問問自己的同事你:「xx,知道select *和select所有欄位的區別麼?    同事:"額。。額。。額。。"   留下的只有尷尬的笑容!我也知道,很多人至今都沒有搞懂select *和selct 所有欄位的區別因此,我開一文來說明一下。另外,我選的是自己最熟悉的mysql資料庫,此文的結論在oralce,sqlserver上是否成立,博主沒做過測試。正文(select所有欄位)性能高?
  • 如何使用MySQL資料庫
    命令格式為「mysqladmin -u root -p 『舊密碼』 password 『新密碼』」。如下圖:在有密碼的情況下,使用「-p」選項來進行密碼校驗。如下圖:註:進入「mysql>」的資料庫操作環境後,用戶可以輸入各種操作語句對資料庫進行管理。
  • 從Web查詢資料庫之PHP與MySQL篇
    因此嘗試連接時需要進行檢查,mysqli_connect_errno()函數將在出現連接 錯誤時返回一個錯誤號,如果成功,則返回0. 請注意: 當連接到資料庫是,通常會議錯誤抑制符@作為第一含代碼。這樣可以巧妙的處理任何錯誤,也可以通過異常來處理。另外,MySQK對同時連接 資料庫的連接數量有一定的限制。
  • MySQL資料庫Insert語句7種寫法
    簡介很多開發人員工作了幾年之後,都會自嘲,自己啥技術都沒學到,就會CRUD,可是我要說的是,CRUD你真的都會嗎,你在MySQL資料庫中,會幾種insert語句寫法呢。在這裡我會7種寫法,下面我就來給大家分別介紹一下。
  • mysql查詢資料庫導致中文亂碼
    mysql查詢資料庫,如果資料庫裡的欄位的值是中文,就會出現亂碼,怎麼解決呢?看下面的講解寫一個test.php的文檔,代碼如下所示,打開mysql的界面,新建一個xml的資料庫,再建一個student的數據表,欄位值和記錄如下圖所示,打開谷歌瀏覽器,運行test.php文檔。運行結果是下圖:看到了吧,出現亂碼了,怎麼辦呢?
  • 資料庫:MySQL 中 「select ... for update」 排他鎖分析
    :select * from goods where id = 1 for update;排他鎖的申請前提:沒有線程對該結果集中的任何行數據使用排他鎖或共享鎖,否則申請會阻塞。在更新數據的時候需要比較程序中的庫存量與資料庫中的庫存量是否相等,如果相等則進行更新,反之程序重新獲取庫存量,再次進行比較,直到兩個庫存量的數值相等才進行數據更新。樂觀鎖適合讀取頻繁的場景。
  • 新手入門MYSQL資料庫命令大全
    一、命令行連接資料庫Windows作業系統進入CMD命令行,進入mysql.exe所在目錄,運行命令mysql.exe -h主機名 -u用戶名 -p密碼注意:參數名與值之間沒有空格 , 如:-h127.0.0.1
  • MySQL資料庫常用命令詳解
    (1)登錄MySQL資料庫用SSH客戶端連接CentOS伺服器,打開終端命令輸入窗口,在終端輸入窗口輸入命令:mysql -uroot –p 該命令用root帳號以密碼方式登錄MySQL,回車後提示輸入密碼
  • MYSQL資料庫操作案例
    MySQL 創建資料庫CREATE DATABASE 資料庫名;以下命令簡單的演示了創建資料庫的過程,數據名為 RUNOOB:[root@host]# mysql -u root -p >Enter password:****** # 登錄後進入終端mysql> create DATABASE RUNOOB;MySQL 刪除資料庫drop database <資料庫名>;
  • day06-python資料庫-mysql之安裝
    資料庫說白了就是文件夾資料庫管理系統就是一個軟體資料庫伺服器:就是對外專門提供數據的一個機器資料庫伺服器,資料庫管理系統,表與記錄的關係:總結:資料庫管理技術的發展歷程人工管理階段---》文件系統階段---》數據系統階段mysql介紹MySQL是一個關係型資料庫管理系統,MySQL最流行的關係型資料庫管理系統,在WEB應用方面MySQL是最好的RDBMS(Relational Database Management System,關係資料庫管理系統