日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL锁机制和PHP锁机制

發布時間:2025/3/8 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL锁机制和PHP锁机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MYSQL中的鎖:
語法 :
LOCK TABLE 表名1 READ|WRITE, 表名2 READ|WRITE .................. 【鎖表】
UNLOCK TABLES? 【釋放表】

Read:讀鎖|共享鎖 : 所有的客戶端只能讀這個表不能寫這個表
Write:寫鎖|排它鎖: 所有當前鎖定客戶端可以操作這個表,其他客戶端只能阻塞
注意:在鎖表的過程中只能操作被鎖定的表,如果要操作其他表,必須把所有要操作的表都鎖定起來!

應用場景:
1. 高并發下單時,減庫存量時要加鎖
2. 高并發搶單、搶票時要使用

error_reporting(0); mysql_connect('localhost','root','admin123'); mysql_select_db('test');# mysql 鎖 mysql_query('LOCK TABLE a WRITE');// 只有一個客戶端可以鎖定表,其他客戶端阻塞在這 $rs = mysql_query('SELECT id FROM a'); $id = mysql_result($rs, 0, 0); if($id > 0) {--$id;mysql_query('UPDATE a SET id='.$id); }# mysql 解鎖 mysql_query('UNLOCK TABLES');

PHP 文件鎖:

bool flock ( int handle, int operation [, int &wouldblock] );
flock() 操作的 handle 必須是一個已經打開的文件指針。operation 可以是以下值之一:

  • 要取得共享鎖定(讀取程序),將 operation 設為 LOCK_SH(PHP 4.0.1 以前的版本設置為 1)
  • 要取得獨占鎖定(寫入程序),將 operation 設為 LOCK_EX(PHP 4.0.1 以前的版本中設置為 2)
  • 要釋放鎖定(無論共享或獨占),將 operation 設為 LOCK_UN(PHP 4.0.1 以前的版本中設置為 3)
  • 如果你不希望 flock() 在鎖定時堵塞,則給 operation 加上 LOCK_NB(PHP 4.0.1 以前的版本中設置為 4)
  • 建兩個文件
    (1) a.php

    $file = "temp.txt"; $fp = fopen($file , 'w'); if(flock($fp , LOCK_EX)){ fwrite($fp , "abc\n"); sleep(10); fwrite($fp , "123\n"); flock($fp , LOCK_UN); } fclose($fp);

    (2) b.php

    $file = "temp.txt"; $fp = fopen($file , 'r'); echo fread($fp , 100); fclose($fp);

    運行 a.php 后,馬上運行 b.php ,可以看到輸出:
    abc
    等 a.php 運行完后運行 b.php ,可以看到輸出:
    abc
    123
    顯然,當 a.php 寫文件時數據太大,導致時間比較長時,這時 b.php 讀取數據不完整

    修改 b.php 為:

    $file = "temp.txt"; $fp = fopen($file , 'r'); if(flock($fp , LOCK_EX)){ echo fread($fp , 100); flock($fp , LOCK_UN); } else{ echo "Lock file failed...\n"; } fclose($fp);

    運行 a.php 后,馬上運行 b.php ,可以發現 b.php 會等到 a.php 運行完成后(即 10 秒后)才顯示:
    abc
    123
    讀取數據完整,但時間過長,他要等待寫鎖釋放。

    修改 b.php 為:

    $file = "temp.txt"; $fp = fopen($file , 'r'); if(flock($fp , LOCK_SH | LOCK_NB)){ echo fread($fp , 100); flock($fp , LOCK_UN); } else{ echo "Lock file failed...\n"; } fclose($fp);

    運行 a.php 后,馬上運行 b.php ,可以看到輸出:
    Lock file failed…
    證明可以返回鎖文件失敗狀態,而不是向上面一樣要等很久。

    結論:
    建議作文件緩存時,選好相關的鎖,不然可能導致讀取數據不完整,或重復寫入數據。
    file_get_contents 好像選擇不了鎖,不知道他默認用的什么鎖,反正和不鎖得到的輸出一樣,是不完整的數據。
    我是要做文件緩存,所以只需要知道是否有寫鎖存在即可,有的話就查數據庫就可以了。

    文件鎖有兩種:共享鎖和排他鎖,也就是讀鎖(LOCK_SH)和寫鎖(LOCK_EX)?
    文件的鎖一般這么使用:

    $fp = fopen("filename", "a"); flock($fp, LOCK_SH) or die("lock error") $str = fread($fp, 1024); flock($fp, LOCK_UN); fclose($fp);

    注意fwrite之后,文件立即就被更新了,而不是等fwrite然后fclose之后文件才會更新,這個可以通過在fwrite之后fclose之前讀取這個文件進行檢查?

    但是什么時候使用lock_ex什么時候使用lock_sh呢??

    讀的時候:?
    如果不想出現dirty數據,那么最好使用lock_sh共享鎖。可以考慮以下三種情況:?
    1. 如果讀的時候沒有加共享鎖,那么其他程序要寫的話(不管這個寫是加鎖還是不加鎖)都會立即寫成功。如果正好讀了一半,然后被其他程序給寫了,那么讀的后一半就有可能跟前一半對不上(前一半是修改前的,后一半是修改后的)?
    2. 如果讀的時候加上了共享鎖(因為只是讀,沒有必要使用排他鎖),這個時候,其他程序開始寫,這個寫程序沒有使用鎖,那么寫程序會直接修改這個文件,也會導致前面一樣的問題?
    3. 最理想的情況是,讀的時候加鎖(lock_sh),寫的時候也進行加鎖(lock_ex),這樣寫程序會等著讀程序完成之后才進行操作,而不會出現貿然操作的情況?

    寫的時候:?
    如果多個寫程序不加鎖同時對文件進行操作,那么最后的數據有可能一部分是a程序寫的,一部分是b程序寫的?
    如果寫的時候加鎖了,這個時候有其他的程序來讀,那么他會讀到什么東西呢??
    1. 如果讀程序沒有申請共享鎖,那么他會讀到dirty的數據。比如寫程序要寫a,b,c三部分,寫完a,這時候讀讀到的是a,繼續寫b,這時候讀讀到的是ab,然后寫c,這時候讀到的是abc.?
    2. 如果讀程序在之前申請了共享鎖,那么讀程序會等寫程序將abc寫完并釋放鎖之后才進行讀。?

    轉載于:https://www.cnblogs.com/5aiQ/p/9486214.html

    總結

    以上是生活随笔為你收集整理的MySQL锁机制和PHP锁机制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。