Mysql交易:对其他交易查询的影响
Mysql Transaction: Effect on other Transaction query
我正在编写一个应用程序来跟踪金融交易(如银行),以保持余额。正如 Here and Here.
所讨论的,我正在使用 Denormalizing
技术来控制性能(并且不必在运行时计算余额)
现在,我面临Race Condition
如果两个人同时进行了与同一实体相关的交易,如上所述的余额计算,应return/set 不一致的数据,如答案中所讨论的 Here and Here, And also as suggested..
我要去Mysql Transactions
。
现在我的问题是,
当 mysql 交易正在进行时,其他类似查询会发生什么情况?
我想知道其他事务是否像 Error 500
中那样失败,或者它们是否 排队 并在第一个事务完成后执行。
我还需要知道如何从 php
的角度处理这两种结果。
并且由于这些事务将成为 php 中更大的一组操作的一个元素,其中包含许多先前的 insert
查询,我是否还应该设置一种机制来回滚那些成功执行的操作查询也是如此,因为我希望 Atomicity
不仅在单个查询中而且在整个操作逻辑中也是如此(php)。
编辑 1 :-
另外,如果是前一种情况,我是否应该检查错误,然后等待几秒钟,然后在一段时间后再次尝试该特定交易查询?
编辑 2 :-
另外 Mysql Triggers
不是 我的选择。
像这样的代码,没有竞争条件。相反,一个事务可能会被中止(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;
并在每一步检查错误。如果出错,回滚并重新运行事务。第二次,它可能会成功。如果不是,则中止——这可能是一个逻辑错误。只有这样你才应该给 http error 500
.
当两个用户 "simultaneously" 尝试进行类似的交易时,将发生以下情况之一:
- 'second' 用户将暂停,直到第一个完成。
- 如果该摊位超过
innodb_lock_wait_timeout
,则说明您的查询速度太慢或其他原因。你需要修复系统。
- 如果你得到一个"Deadlock",可能有修复代码的方法。同时,简单的重启交易也有可能成功。
但它不会弄乱数据(假设逻辑正确)。
没有必要 "wait a second" -- 除非您有需要 "a second" 的交易。对于这种类型的代码,这样会非常慢。
我所说的适用于"real money"、非真实货币、非货币等;有什么需要仔细统计的。
我正在编写一个应用程序来跟踪金融交易(如银行),以保持余额。正如 Here and Here.
所讨论的,我正在使用Denormalizing
技术来控制性能(并且不必在运行时计算余额)
现在,我面临Race Condition
如果两个人同时进行了与同一实体相关的交易,如上所述的余额计算,应return/set 不一致的数据,如答案中所讨论的 Here and Here, And also as suggested..
我要去Mysql Transactions
。
现在我的问题是,
当 mysql 交易正在进行时,其他类似查询会发生什么情况?
我想知道其他事务是否像 Error 500
中那样失败,或者它们是否 排队 并在第一个事务完成后执行。
我还需要知道如何从 php
的角度处理这两种结果。
并且由于这些事务将成为 php 中更大的一组操作的一个元素,其中包含许多先前的 insert
查询,我是否还应该设置一种机制来回滚那些成功执行的操作查询也是如此,因为我希望 Atomicity
不仅在单个查询中而且在整个操作逻辑中也是如此(php)。
编辑 1 :- 另外,如果是前一种情况,我是否应该检查错误,然后等待几秒钟,然后在一段时间后再次尝试该特定交易查询?
编辑 2 :-
另外 Mysql Triggers
不是 我的选择。
像这样的代码,没有竞争条件。相反,一个事务可能会被中止(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;
并在每一步检查错误。如果出错,回滚并重新运行事务。第二次,它可能会成功。如果不是,则中止——这可能是一个逻辑错误。只有这样你才应该给 http error 500
.
当两个用户 "simultaneously" 尝试进行类似的交易时,将发生以下情况之一:
- 'second' 用户将暂停,直到第一个完成。
- 如果该摊位超过
innodb_lock_wait_timeout
,则说明您的查询速度太慢或其他原因。你需要修复系统。 - 如果你得到一个"Deadlock",可能有修复代码的方法。同时,简单的重启交易也有可能成功。
但它不会弄乱数据(假设逻辑正确)。
没有必要 "wait a second" -- 除非您有需要 "a second" 的交易。对于这种类型的代码,这样会非常慢。
我所说的适用于"real money"、非真实货币、非货币等;有什么需要仔细统计的。