在高並發下,如果我插入一條資料,返回一個
insert_id
,那麼這個
insert_id
會不會為別人所用呢。如果不被別人所用,php是怎麼做到訪問隔離的。
回複內容:
在高並發下,如果我插入一條資料,返回一個insert_id
,那麼這個insert_id
會不會為別人所用呢。如果不被別人所用,php是怎麼做到訪問隔離的。
樓主的理解有問題。。。
MySQL的LAST_INSERT_ID()或者說PHP的mysql_insert_id(connection)。
請注意,Connection!
每次插入資料,MySQL會返回資料給【當前的資料庫連接】,告知是插入到第幾個位置(ID)的。
根本不存在什麼"訪問隔離
","為別人所用
"之類的問題。
——————————————————————————————————————————————————
資料庫的存在,本身就是為瞭解決並發的問題。
查詢是可以並發的(同時讀取檔案不會有問題)。
插入、修改、刪除必須是隊列方式(同時修改同一個檔案???)。
樓主的理解有問題,一個等一個就會一卡一卡的?
舉個栗子,現在的一般的機械硬碟的寫入速度30-50M/s。
一次SQL寫入請求,平均寫入3-5KB資料(你TM在逗我,怎麼可能這麼多),那麼理論上,也可以支援10000/s的並發量。
什麼叫一卡一卡的 = =
—————————————————————————————————————————————————
回想當年……2333333……
當初我還不會PHP的時候被同學拉去做網站,報名參加活動的那種只有幾個網頁的網站。
資料提交之後,在PHP裡,我就自己定義了一個格式,一條資料一行,把資料全都儲存到一個txt檔案裡。
(在相當長一段時間裡,我都覺得,資料庫貌似也沒那麼重要啊,直接讀寫檔案不就完了)
直到後來……
同時對一個檔案進行寫操作就會發生異常(很底層的問題,作業系統層級的)。
同時對一個檔案加鎖(防止同時寫操作),也可能發生異常(還是作業系統層級的問題)。
對txt的指定位置進行修改,刪除,必須從檔案裡全部讀入記憶體,然後處理,然後寫到檔案裡。
想修改格式,查詢,排序……全都要全部讀取全部寫入。
這時候遇到並發的問題……徹底爆炸,資料各種丟失錯誤混亂。。。
資料庫已經基本是相當完美的解決了這些亂七八糟的問題了。。。
嗯,是的,每個請求的連結都是獨立的,10個並發就是10個連結化物件,所以insert_id永遠不會被其他請求的連結所用!!!
php層面的“隔離”
這個就是PHP的“特性”---每個請求都是一個進程,php-fpm每次都會分配一個對應的worker來處理這個請求。
每個操作都在對應的php-fpm下屬的worker下進行,記憶體管理也是一樣。
處理完這個進程就關閉。
你插入的返回id是在各自請求對應的php-fpm下屬的worker記憶體中,不會出現你說的情況。
mysql層面的“隔離”
跟引擎有關咯。簡單說引擎對應的寫入處理不同。MyIASM是表鎖,Innodb是行鎖,都可以在一定程度上避免並發問題。再高的並發,就要用其他的處理方式了,比如隊列等等。
php即便是高並發,單進程連資料庫還是單個串連的。
insert id是根據mysql串連的上一條insert語句返回的。
所以對於一個php進程,一個mysql串連,返回的insert id是不會混亂的
兄弟啊,你需要看一本書叫資料庫原理
,資料庫裡面有一個概念叫ACID,事務就兩種狀態,成功和失敗。你這邊都insert進去了,那就是成功了,就last insert id
也是這個事務的傳回值。
MySQL本身也支援並發,開N個connection去同步的insert,也不會有問題,最多就是慢一點。
PS:PHP能寫出來多高的並發??
php中一個請求一般新產生一個mysql串連,多個session同時請求mysql插入操作如何同步,這是mysql解決的問題。mysql 插入操作是加鎖的,保證了原子性。
@MrGeneral 說的有部分問題,在這裡貼出來,大家補充下:
---每個請求都是一個進程,每次都會啟動一個php-fpm。
這句話,每個請求都是一個進程,沒錯,但是每次都會啟動一個php-fpm?
這個是不對的,每次都會啟動一個fastcgi的進程,但是這個進程是不是每一次都重新建立的,那倒未必,可能是從php-fpm維護的”進程池“裡面取的,也就是說,php-fpm負責進程的管理,部分最佳化,比如cache住啊,避免了每次都建立進程的開銷。而php-fpm本身是常駐的。
求反駁~