I am developing an Internet Banking, running on Google App Engine and developed in PHP.
Race condition is a big concern. Users can't ever have less than $0.00 (I know that I have other problems to worry about, but let's focus just on this one right now).
Pseudo-code:
<?php
$user_id = $_GET['user_id'];
$withdraw_amount = $_GET['withdraw_amount'];
if(getUserBalance($user_id) - $withdraw_amount >= 0){
setUserBalance($user_id, getUserBalance($user_id) - $withdraw_amount);
sendMoneyToUser($user_id, $withdraw_amount);
echo 'Success';
}
else{
echo 'Insufficient funds';
}
?>
Google Cloud SQL Database:
USER_ID BALANCE
1 10.00
2 20.00
The above database is a very simplistic version of the actual database. SQL lock tables/rows would not work for me in the real world.
How can I prevent race conditions?
Remember, the code is running on Google App Engine and I don't have access to PHP Semaphores extension.
I am developing an Internet Banking, running on Google App Engine and developed in PHP.
Race condition is a big concern. Users can't ever have less than $0.00 (I know that I have other problems to worry about, but let's focus just on this one right now).
Pseudo-code:
<?php
$user_id = $_GET['user_id'];
$withdraw_amount = $_GET['withdraw_amount'];
if(getUserBalance($user_id) - $withdraw_amount >= 0){
setUserBalance($user_id, getUserBalance($user_id) - $withdraw_amount);
sendMoneyToUser($user_id, $withdraw_amount);
echo 'Success';
}
else{
echo 'Insufficient funds';
}
?>
Google Cloud SQL Database:
USER_ID BALANCE
1 10.00
2 20.00
The above database is a very simplistic version of the actual database. SQL lock tables/rows would not work for me in the real world.
Race Condition case:
GAE instance #1 GAE instance #2
user_id = 1 user_id = 1
balance = 10 balance = 10
withdraw_amount = 10 withdraw_amount = 10
10 - 10 >= 0 (true) 10 - 10 >= 0 (true)
sendMoneyToUser(1, 10) sendMoneyToUser(1, 10)
User gets $10 User gets $10
The user now has $20 in his hands, but he had just $10 in the bank!!!