Mysql rubyonrails中的读锁

Mysql rubyonrails中的读锁,mysql,ruby-on-rails,ruby,postgresql,locking,Mysql,Ruby On Rails,Ruby,Postgresql,Locking,在Rails中似乎没有一种内置的方式来获取读取锁(对于表)。我知道这些通常并不理想,但我的用例似乎需要一个: 分配中可用的票证数量有限,我希望为整个事务设置一个读锁,如下所示: 检查是否还有足够的车票 将它们全部分配到此事务(通过在票证表中创建行) 如果两个请求同时执行第一步,可能会创建太多的票证对象,因为可用票证的数量在平均时间内发生了变化(竞赛条件) 是否有其他更好地遵循rails思维的方法来实现这一点,或者我是否需要根据需要手动锁定和解锁 (理想情况下,解决方案是数据库无关的) 谢谢 我同

在Rails中似乎没有一种内置的方式来获取读取锁(对于表)。我知道这些通常并不理想,但我的用例似乎需要一个:

分配中可用的票证数量有限,我希望为整个事务设置一个读锁,如下所示:

  • 检查是否还有足够的车票
  • 将它们全部分配到此事务(通过在票证表中创建行)
  • 如果两个请求同时执行第一步,可能会创建太多的票证对象,因为可用票证的数量在平均时间内发生了变化(竞赛条件)

    是否有其他更好地遵循rails思维的方法来实现这一点,或者我是否需要根据需要手动锁定和解锁

    (理想情况下,解决方案是数据库无关的)


    谢谢

    我同意您的看法,在您的用例中必须同步对数据库的访问。除了使用锁,您还可以使用队列序列化数据库操作:在一个时间点上只有一个操作可以访问您的数据库-我认为这是一个更高级的管理并发访问资源的模型。锁对死锁是敏感的,我会不惜一切代价避免死锁


    另一种可以解决问题的策略(但依赖于数据库)是使用事务隔离级别“serializable”

    坦率地说,我不记得active_记录管理数据库级锁。整个“rails-way”范式在一定程度上违背了许多好的dba习惯用法(以STI为例)。所以,是的,你被手动锁定卡住了。不过,您可以使用某个互斥类(或任何其他类)来实现它


    第二个选择是重新思考您的解决方案。您可以很好地使用某种封顶集合/队列。

    使用队列对我来说很有意义,我只是觉得很奇怪ActiveRecord(事实上,大多数ORM都不提供任何类型的表锁定)。不喜欢它这样做,但是(正如我对@Tom的回答的评论)某种类型的队列似乎是一种可行的方式。不确定最佳方法,因为理想情况下,它不依赖于共享内存或类似的东西。您应该将队列与原子推送/弹出操作一起使用。例如,redis是一个很好的语言不可知工具。