2016-06-12 146 views
0

可以說我想在每次訪問某個網頁時在數據庫中增加一個計數器。php和mySQL數據庫併發更新

稱爲 '示例' 數據庫看起來是這樣的:

|名稱..... |值.......... | id |

===================

|計數...... | 5 ................ | 1 | < ----第一排

和網頁上的代碼如下所示:

$db = mysqli_connect("localhost", ....); 
$q = "SELECT Value FROM example WHERE id = '1'"; 
$r=mysqli_query($db, $q); 
$result = mysqli_fetch_array($r); 
$increment = $result[0] + 1; 
$q = "UPDATE example SET Value = '$increment' WHERE id = '1'"; 
mysqli_query($db,$q); 

如果兩個人在同一時間訪問該網頁,一個人將獲取的5緊接着價值那人B就會獲得相同的價值。他們都會將它增加到6,並且兩個都會一個接一個地輸入6作爲計數器值,因爲有兩個人訪問該頁面時它應該是7。我怎樣才能防止這一點?

+2

**警告**:使用'mysqli'時,您應該使用[參數化查詢](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php)和['bind_param' ](http://php.net/manual/en/mysqli-stmt.bind-param.php)將用戶數據添加到您的查詢。 **不要**使用手動轉義和字符串插值或串聯來實現此目的,因爲如果您忘記正確地轉義某些內容,您將創建嚴重的[SQL注入漏洞](http://bobby-tables.com/)。 – tadman

回答

2

你可以做一個聲明:

"UPDATE example SET Value = Value + 1 WHERE id = '1'"; 

所以也沒有其他任務可以在讀取和更新之間改變它。

這裏腳本

$ DB = mysqli_connect( 「本地主機」,....); $ q =「更新示例SET值=值+ 1 WHERE id ='1'」; mysqli_query($ db,$ q);

+2

準確。像這樣的原子更新要比做一個只需要競爭條件的讀/寫週期好得多。 – tadman

+0

但行:mysqli_query($ db,$ q);仍然是必需的。 難道不可能有同樣的情況如果人A執行更新線並且人B在此之後立即執行更新線,那麼在人A運行下面的線之前? – Jay

+0

@Jay - 如果您只使用更新結果是7在您的問題 –