代码之家  ›  专栏  ›  技术社区  ›  Toms Mikoss

选择使用MySQL锁定Rails

  •  5
  • Toms Mikoss  · 技术社区  · 15 年前

    寻求最佳实践建议:

    假设我有一个具有limit属性的account对象。每天可以有n笔付款,其总额达到账户限额。创建新付款时,它检查其金额+当天其他付款的金额是否仍在帐户限制内,并保存记录或显示错误。

    现在,假设我有一个限额为100美元的账户,同时创建了两个99美元的付款。每一个都会做一个选择,看到没有任何东西,然后继续保存自己,结果总共保存了198美元。

    你会怎么做?我在考虑在交易开始时对付款表发出写锁,但这似乎相当繁重,因为我只关心不允许属于特定账户的付款不被其他交易读取。有没有其他的选择,更好的方法来处理这种情况?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Marcos Toledo    15 年前

    我在考虑在交易开始时在支付表上发出一个写锁,但这似乎是明智之举。

    假设您已经在谈论事务,我假设您没有使用myisam,而是使用innodb或其他已经支持事务的引擎。

    锁定读或写事务以保持操作的原子性不是应该手动执行的操作。这是你交易的工作 隔离级别 这样做。这还将保留事务打开和表或记录锁定之间操作的原子性,这样就不会有读操作同时溜入。

    对于您描述的用例,您需要的是具有“可序列化”隔离级别的事务,该级别将为读和写而锁定。此外,它将只自动锁定从中读取的记录(即使查询范围),因此剩下的记录可以自由操作。

    通过“可序列化”隔离级别,从表中读取信息时,任何更新或读取这些记录的尝试都必须等待该事务完成。另外,在更新同一个事务之前,请确保您已经阅读了,这样您就可以确保使用正确的值。

    您可以在此处阅读有关隔离级别的更多信息: http://en.wikipedia.org/wiki/Isolation_(database_systems) http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm

    您可以在这里学习如何设置事务的隔离级别: http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html