【问题标题】:How to separate logic from data access while maintaining application level concurrency in database如何在数据库中保持应用程序级并发的同时将逻辑与数据访问分离
【发布时间】:2020-08-27 17:41:12
【问题描述】:

我正在尝试为某件商品预订订单。但要做到这一点,我需要能够获取项目并锁定它们,以便在我更新或释放锁之前阻止其他并发读取和写入。保证调用 release 的方式是使用 try-finally 块。

如何在保持逻辑和数据访问关注点分离的同时阻止对表或某些行的读取和写入?

用例大致如下:

def use_case(input, repository):
    validate_input(input)
    try:
        data = repository.get_data()

        if condition1 and condition2:
            update_data()
    finally:
        repository.unlock()

我实现存储库的方式是:

class Repository:
    def get_data():
         conn = adapter.connect()
         cur = conn.cursor()

         cur.execute('select * from table where condition')

         cur.close()
         conn.close()

    def update():
         conn = adapter.connect()
         cur = conn.cursor()

         cur.execute('update table set field = value where condition')

         cur.close()
         conn.close()
    
    def unlock():
         pass

我尝试过选择更新、显式锁定和咨询锁,但它们都在连接关闭时释放,这是正确的。

我本可以使用乐观锁定,但问题是我一次更新多个列。即使一次列的值发生变化,我也需要重新运行我的逻辑。

我创建单独连接的原因是通过仅在需要时创建它们来避免空闲连接。我不知道这是否是标准的做事方式。

【问题讨论】:

  • 您的用例不清楚。如果您想锁定行的时间超过数据库连接,您如何确保行不会永远留在原地?您如何确定谁可以拨打updata_data 以及谁被锁定?请详细描述你的目标。对我来说,这看起来不像“经典选择更新问题”。
  • 我试图更好地传达我的意图@LaurenzAlbe。立即检查问题
  • @LaurenzAlbe 有没有办法在不编写获取数据、验证输入和更新数据的单体应用的情况下做到这一点?
  • 我不知道你所说的单体是什么意思。也就是说,我知道单体是什么,但我不明白它是如何引用你的 10 行代码的。
  • 也许我基本上是想问我可以使用什么锁,它与连接无关@LaurenzAlbe。答案可能是乐观锁

标签: python database postgresql separation-of-concerns


【解决方案1】:

基本上有两种选择:乐观锁和悲观锁:

  • 使用悲观锁定,所有事情都发生在单个数据库事务中。你SELECT ... FOR UPDATE,你通过提交事务来释放锁。

    如果整个动作很短(没有用户交互!),悲观锁定是好的,特别是如果冲突的可能性很高。

  • 乐观锁定不绑定到数据库事务(尽管您可以使用REPEATABLE READ 事务来实现它)。您记住所有列的原始值并使用UPDATEWHERE 条件来检查所有值是否仍然相同(没有人修改该行)。如果并发事务修改了行(没有更新行),则重复整个操作。

    如果操作需要很长时间或发生冲突的可能性很低,那么乐观锁定是很好的。

【讨论】:

  • 我知道锁定。问题是锁定,你需要在同一个事务中。我不知道最佳实践,但如果您看起来正确,我正在为选择和更新创建不同的连接。我这样做是为了方便测试,因为没有状态。如果我在构造函数中创建连接对象,我可能有一个空闲连接太久。唯一真正的选择似乎是乐观锁定。唯一的问题是因为我需要保留全部或全部,如果发生冲突,我需要重新运行我的业务逻辑
  • 我的问题更多是关于如何将业务逻辑与数据库分离,同时锁定不同的连接,而不是在这种情况下如何以及使用哪个锁
猜你喜欢
  • 1970-01-01
  • 2011-03-06
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
相关资源
最近更新 更多