BEGIN; SELECT COUNT(*) INTO @n FROM Duties WHERE Shift=@s AND Status='on duty' FOR UPDATE; if @n > 1 then UPDATE Duties SET Status='reserve' WHERE DoctorId=@d AND Shift=@s; COMMIT; else ROLLBACK;
If you're not familiar with InnoDB, the SELECT establishes a critical section covering the on duty doctors. This same sequence executing concurrently will block until the connection with the lock has checked the count. The COMMIT (or ROLLBACK) will unblock the other connection waiting for the lock. In case the first connection committed an UPDATE which reduced the count to 1, the second connection, when unblocked, will see the new count of 1 and not make any update.