imagine this scenario, I have a website on which users get credit from activity, for example, selling their products or clicking on ads or so that my users table would be something like this
users : id , username , credit 15 , alex , 1000 16 , jack , 1500
so now users can request a loan withdrawal in some form, my review table will be something like this
withdraws : id , user_id , amount 1 , 15 , 500 2 , 16 , 100
I need to subtract the amount from their loan ... I like to do this with a trigger
CREATE TRIGGER withdraw BEFORE INSERT ON withdraws FOR EACH ROW BEGIN UPDATE users SET credit = credit-NEW.amount WHERE id = NEW.user_id; END $$
and to make sure that users cannot get negative credit during the withdrawal process, I have this trigger (from the curse I will also check this in the code logic)
CREATE TRIGGER update_user BEFORE UPDATE ON users FOR EACH ROW BEGIN IF NEW.credit < 0 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'invalid credit error'; END IF; END $$
Now my question is: is it possible that someone, intentionally or through some server error, will send several withdrawal requests at the same time and withdraw more than his credit .... and if so, how can I prevent this?
Do I need to lock the user table before each insert to insert, or something like this?
update: if I am going to lock the user line and use the transactional wrapper for the whole operation ... it seems reasonable, but how does the trigger introduce? I mean, obviously, I need to start the transaction and end / commit it in the code (since I hate stored procedures and never use them) does this mean that I have to give up the trigger and do a subtraction in the code, as well as somehow run inside a transaction, despite being launched / executed on another platform / location