【发布时间】:2018-01-29 15:48:55
【问题描述】:
我有一个带有 MySQL/Doctrine ORM 的简单 Silex Web 应用程序。每个用户都有balance(这是一个简单的应用程序,所以只是列就可以了),我需要在一些操作后减少它(当然检查它是否> 0)。
据我了解,我可以使用乐观锁定来避免冲突/漏洞。我已阅读文档http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html,但找不到任何有关使用它的完整示例。
从哪里获得“预期版本”?我是否需要将其作为输入(隐藏表单字段)传递?还是有更好的方法?文档说了一些关于会话的内容,但我不知道如何将它存储在那里(更新每个请求的会话?)。
此外,如果我将其作为输入传递,那么据我所知,在捕获OptimisticLockException 后没有办法自动重复查询而不通知用户? (例如,如果用户打开两个选项卡并在其中一个一个提交请求)
我的目标只是防止用户同时发送多个请求并且余额仅减少一次等潜在问题。因此,能够在不涉及用户的情况下在锁定错误时自动重复它会很好。因为如果我通过表单传递它,那么很可能会因为多个选项卡而出现此错误。所以看起来有点复杂,也许除了乐观锁定还有别的东西?
【问题讨论】:
-
有点宽泛的问题。我没有适合你的工作示例。基本思想是,您需要先保存实体的当前版本,然后再将其传递给用户进行编辑。您可以使用隐藏的表单元素来做到这一点,但您会冒着一些快乐的小丑用户更改它的价值的风险。将其存储在会话中可以消除这种风险。当然,您必须根据每个请求对其进行更新。当版本不再匹配时该怎么做取决于您。在不通知用户的情况下丢弃用户的更改似乎有点粗鲁。
-
@Cerad 谢谢 :) 就我而言,我没有什么可丢弃的,它只是一个开始(排队)某些操作的按钮。但我的目标只是防止用户同时发送多个请求并且余额仅减少一次等潜在问题。因此,能够在不涉及用户的情况下自动重复锁定错误会很好。因为如果我通过表单(我猜也是在会话中)传递它,那么很可能由于多个选项卡而出现此错误。所以看起来有点复杂,也许我应该使用其他东西而不是乐观锁定?
-
我认为 CQRS 和事件溯源更接近你想要的。 kenneth-truyers.net/2013/12/05/… 和 cqrs.nu 乐观锁定实际上是关于两个或更多用户尝试同时更新同一记录。
-
请提供
SHOW CREATE TABLEOptimistic 何时使用和何时不使用。我正在寻找一个有助于“乐观”算法的额外专栏(可能是TIMESTAMP)。 -
@RickJames 你是什么意思?我打算像上面的文档一样使用
version整数列。
标签: php mysql sql concurrency doctrine-orm