我正在编写一份应追踪金融交易(如银行)的申请,以维持余额。我正在使用Denormalizing
技术来检查性能(而不必在运行时计算余额),如Here和Here所述。
现在,如果两个人同时执行与同一实体相关的交易,我面临Race Condition
,如上所述,余额计算应返回/设置不一致的数据,如上所述{ {3}}和Here,以及答案中的Here ..
我要去Mysql Transactions
。
现在我的问题是,
我希望知道其他交易是否会在Error 500
中失败,或者在第一次交易完成后是否排队并执行。
我还需要知道如何处理php
观点的结果。
由于这些事务将成为php中具有许多先前insert
查询的更大操作集的元素,我是否还应该设置一种机制来回滚那些成功执行的查询,因为我想要Atomicity
不仅在个别查询中,而且在整个操作逻辑(php)中。
编辑1: - 此外,如果是前者,我应该检查错误,并等待几秒钟,并在一段时间后再次尝试特定的交易查询?
编辑2: -
另外Mysql Triggers
不对我来说是一个选项。
答案 0 :(得分:1)
使用这样的代码,没有竞争条件。相反,可以中止一个事务(ROLLBACK'd)。
BEGIN;
SELECT balance FROM Accounts WHERE acct_id = 123 FOR UPDATE;
if balance < 100, then ROLLBACK and exit with "insufficient funds"
UPDATE Accounts SET balance = balance - 100 WHERE acct_id = 123;
UPDATE Accounts SET balance = balance + 100 WHERE acct_id = 456;
COMMIT;
并检查每一步的错误。如果错误,ROLLBACK并重新运行该事务。第二次,它可能会成功。如果没有,那么中止 - 这可能是一个逻辑错误。只有这样你才能给http error 500
。
当两个用户“同时”尝试进行类似的交易时,会发生以下事情之一:
innodb_lock_wait_timeout
,则您的查询速度太慢或其他原因。你需要修理系统。但它会不搞乱数据(假设逻辑正确)。
没有必要“等一下” - 除非您的交易需要“一秒钟”。对于这种类型的代码,这种情况会非常缓慢。
我说的是“真钱”,非真钱,非钱等;无论你需要仔细记录。