2015-09-11 135 views
2

假設我有一個函數用於在某些情況下將數據庫中名爲project_id的列加1。 (由於在確定是否增加之前必須運行邏輯,因此假定自動增量不會滿足此用例。同步PHP數據庫查詢

當用戶單擊「新建項目」,該功能在數據庫中查找當前最大的PROJECT_ID,做一些其他的東西,並通過1

遞增PROJECT_ID添加行有沒有一種可能,當多個用戶連接時,服務器處理某個其他消息所需的時間會導致多個用戶獲取相同的project_id?如果是這樣,你會如何去避免這個問題?以這種方式增加是一個壞主意嗎?

下面是一個例子。這個例子是基於Laravel的,但這個問題一般適用。

function ReallyLongFunction() { 
    //figure out what the current max project_id is and increment by 1 
    $newProjectId = Project::max("project_id")+1; 


    //Some other stuff that the server has to do. I am exaggerating here the length of time. 
    //If another user triggers this function, will both users will have the same project id? 
    sleep(2); 

    //Insert new row into database 
    $project = new TempProject; 
    $project->project_id = $newProjectId; 
    $project->save(); 
} 
+0

我不是數據庫專家,但我會說,是的,這是不好的做法。如果您試圖在代碼中正確執行自動增量,爲什麼不自動遞增工作? – samrap

+0

每次用戶按下「新建項目」按鈕時,您可以在數據庫中創建一個「草稿」記錄,並在取消時刻錄新的自動增量ID。 – Scuzzy

回答

2

在你自己的代碼中做一個好主意sql server在內部可以做得更好。 $newProjectId = Project::max("project_id")+1;聽起來非常像auto_increment的替代品。但是,如果你的要求是比這更復雜,你需要locks

[LOW_PRIORITY]寫鎖:

持有鎖可以讀取和寫入表中的會話。

只有擁有該鎖的會話才能訪問該表。其他 會話可以訪問它,直到鎖定被釋放。

在保持WRITE 鎖的同時鎖定其他會話對該表的請求。

LOW_PRIORITY修飾符影響鎖定調度,如果WRITE鎖 請求必須等待(稍後介紹)。

如果因任何表上的其他 會話持有的鎖而必須等待LOCK TABLES語句,則會阻塞,直到所有鎖都可以獲得 。

如果很多用戶同時訪問同一頁面,則響應將開始減慢,因爲第二個請求無法提供,直到第一個請求完成爲止。

+1

感謝您的快速回復......您已確認我的懷疑,這並非是最好的辦法。 – Andrew