I am using InnoDB and have the following table
officeRechNr
year | month | id |
------------------------
2016 | 7 | 2 |
2016 | 6 | 5 |
2016 | 5 | 6 |
My script works as follows:
Get id from officeRechNr from current year and month
Increase id by one and update in officeRechNr
Echo increased id
So if the script would be executed one after another, I would expect:
New id is 3
New id is 4
New id is 5
I assumed that this behaves differently when I execute the script parallel.
Here is my script:
$db = new mysqli("localhost","user","pass","db");
$year = date("Y");
$month = date("m");
$stmt = $db->prepare('SELECT zahl FROM officeRechNr WHERE jahr = ? AND monat = ?');
$stmt->bind_param('ii', $year, $month);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$number = $row['zahl'] + 1;
sleep(20);
$stmt = $db->prepare('UPDATE officeRechNr set zahl = ? WHERE jahr = ? and monat = ?');
$stmt->bind_param('iii',$number, $year, $month);
$stmt->execute();
echo "New id is $number";
I executed both scripts simultaneously, so I assumed $number must be equal to 3 for both scripts and then they sleep for 20 seconds. Therefore I would expect
New id is 3
New id is 3
to my surprise, the outcome was
New id is 3
New id is 4
I thought I need to write-lock the database to achieve this result, as explained in Lock mysql table with php.
Why did I not get the expected outcome? Does this script always return different id's - even if executed at exact same time?