【问题标题】:Mysql Transaction: Effect on other Transaction queryMysql Transaction:对其他事务查询的影响
【发布时间】:2015-07-30 12:45:36
【问题描述】:

我正在编写一个应用程序来跟踪金融交易(如在银行中),以维持余额。正如HereHere 所讨论的,我正在使用Denormalizing 技术来控制性能(并且不必在运行时计算余额)。

现在,我面临Race Condition,如果两个人同时进行了与同一实体相关的交易,如上所述的余额计算将返回/设置不一致的数据,如Here 所述和Here,以及答案中的suggested..

我要去Mysql Transactions

现在我的问题是,

当一个 mysql Transaction 正在进行时,其他类似的查询会发生什么?

我想知道其他事务是否像 Error 500 一样失败,或者它们是否排队并在第一个事务完成后执行。

我还需要知道如何从php 的角度处理任一结果。

由于这些事务将成为 php 中更大的一组操作的一个元素,其中包含许多先前的 insert 查询,我是否还应该设置一种机制来回滚那些成功执行的查询,因为我想要 @987654332 @ 不仅在单个查询中,而且在整个操作逻辑(php)中。

编辑 1:- 另外,如果是前者,我是否应该检查错误,并等待几秒钟,然后在一段时间后再次尝试该特定事务查询?

编辑 2:- Mysql Triggers 对我来说不是一个选项。

【问题讨论】:

  • 我希望这里没有真正的
  • 没有,但是我们的积分系统还是一样的,最终还是以真币提现,但是人工验证到位,只能离线提现。
  • 无论您得到什么答案 - 唯一重要的一点是:如果您的银行将实施您的代码,您是否相信您的代码始终能在您的银行账户中正常工作?
  • 如果您出于性能目的(以及更轻松的概览)实现余额金额,那么您不要让 X 个可能的流程这样做。你只有一个人这样做,永远。因此,不会出现竞争条件。您可以使用多种工具 - 队列、mysql 事件调度程序等。很难正确地引导您朝着正确的方向前进,因为您正在处理的整个会计都不清楚。
  • @RyanVincent 当然,我确实“信任”我的代码,正如我在问题中解释的那样,我正在努力使其尽可能减少错误,同时处理所有输入验证,我现在正在思考可能会出现错误的地方,目前这似乎是重点。不过,谢谢您的评论。

标签: php mysql sql database-design transactions


【解决方案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;

并在每一步检查错误。如果错误,回滚并重新运行事务。第二次,它可能会成功。如果不是,则中止——这可能是一个逻辑错误。只有这样你才应该给http error 500

当两个用户“同时”尝试进行类似的交易时,就会发生以下情况之一:

  • “第二个”用户将被暂停,直到第一个用户完成。
  • 如果该档位大于innodb_lock_wait_timeout,则您的查询太慢或其他原因。您需要修复系统。
  • 如果您遇到“死锁”,可能有办法修复代码。同时,简单地重新启动事务很可能会成功。

但它不会弄乱数据(假设逻辑正确)。

没有必要“等待一秒钟”——除非您有需要“一秒钟”的交易。对于这种类型的代码,这样会非常慢。

我所说的适用于“真钱”、非真钱、非钱等;任何你需要仔细计算的东西。

【讨论】:

  • 感谢您的回答,您的意思是,查询应在内部排队(因为我的查询不应超过几微秒),最终用户不必重新启动查询,从外面看都是无缝的?
  • “锁定等待”是无缝的,除了难以察觉的延迟。 “死锁”对其中一项事务来说是致命的,因此需要检查错误并重播BEGIN...COMMIT。如果一个连接正在将“资金”从帐户#123 转移到 456,并且同时另一个连接正在向相反方向转移资金,我给出的示例可能会出现死锁。
  • 再次感谢,您的反馈很有帮助。
猜你喜欢
  • 1970-01-01
  • 2016-10-14
  • 2022-08-02
  • 2013-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多