2012-06-30 77 views
3

我需要在我的一個項目中使用batchId,一行或多行可以有單個batchId。所以當我從單個用戶插入一串1000行時,我會給這1000行添加一個batchId。這個batchId是下一個自動增量batchId。在PHP/MySQL中手動增加計數器的最佳方法是什麼?

目前,我爲unique_ids維護一個單獨的數據庫表,並在那裏存儲最後一個batchId。 每當我需要在表中插入一批行時,我將unique_ids表中的batchId更新爲1,並將其用於批插入。

update unique_ids set nextId = nextId + 1 where `key` = 'batchId'; 

select nextId from unique_ids where `key` = 'batchId'; 

我調用了一個函數,該函數在兩個查詢之上觸發,並返回批處理(batchId)的nextId。

這是我的PHP類和函數調用相同。我正在使用ADODB,您可以忽略與ADODB相關的代碼。

 class UniqueId 
     { 
       static public $db; 

       public function __construct() 
       { 

       } 

       static public function getNextId() 
       { 
         self::$db = getDBInstance();   
         $updUniqueIds = "Update unique_ids set nextId = nextId + 1 where `key` = 'batchId'"; 
         self::$db->EXECUTE($updUniqueIds); 

         $selUniqueId = "Select nextId from unique_ids where `key` = 'batchId'"; 
         $resUniqueId = self::$db->EXECUTE($selUniqueId); 

         return $resUniqueId->fields['nextId']; 
       } 
     } 

現在,無論何時我需要下一個batchId,我只需調用下面的代碼行。

`$batchId = UniqueId::getNextId();` 

但真正的問題是,當有數百個同時請求在第二,它提供了相同的batchId兩個不同批次。這對我來說是一個嚴重的問題。我需要解決這個問題。

請問我該怎麼辦?我是否可以僅限制此類的單個實例,因此沒有同時發生的請求可以一次調用此函數,並且絕不會將一個批次標識提供給兩個不同的批次。

回答

3

查看原子操作或事務。它將鎖定數據庫,並且只允許在任何給定實例中及時進行一次寫入查詢。

這可能會影響您的表現,因爲現在其他用戶必須等待解鎖的數據庫!

雖然我不確定ADODB爲atomicity提供哪種支持!

基本概念是:

Acquire Lock 
Read from DB 
Write to DB with new ID 
Release Lock 

如果鎖已經獲得,該腳本將被阻止(忙等待),它再次釋放到。但這樣可以保證不會發生數據危害。

+0

此鎖會使數據庫鎖定或表鎖定?如果它鎖定了數據庫,我無法使用它。 –

-2

的begin tran 更新 選擇 提交

這樣的更新鎖防止兩個併發運行從拉動相同的值。

如果您先選擇共享鎖,則不會隔離這兩個鎖

相關問題