Python 如何在数据库中保持应用程序级并发的同时将逻辑与数据访问分离

Python 如何在数据库中保持应用程序级并发的同时将逻辑与数据访问分离,python,database,postgresql,separation-of-concerns,Python,Database,Postgresql,Separation Of Concerns,我想预订一件商品。但要做到这一点,我需要能够获取项目并锁定它们,以便在更新或释放锁之前阻止其他并发读写。保证调用release的方法是使用try-finally块 如何在保持逻辑和数据访问关注点分离的同时阻止对表或某些行的读写 用例大致如下所示: def用例(输入,存储库): 验证输入(输入) 尝试: data=repository.get_data() 如果条件1和条件2: 更新_数据() 最后: repository.unlock() 我实现存储库的方式是: 类存储库: def get_d

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

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

用例大致如下所示:

def用例(输入,存储库):
验证输入(输入)
尝试:
data=repository.get_data()
如果条件1和条件2:
更新_数据()
最后:
repository.unlock()
我实现存储库的方式是:

类存储库:
def get_data():
conn=适配器。连接()
cur=连接光标()
cur.execute('select*from table where condition')
当前关闭()
康涅狄格州关闭
def update():
conn=适配器。连接()
cur=连接光标()
cur.execute('更新表集合字段=条件所在的值')
当前关闭()
康涅狄格州关闭
def unlock():
通过
我尝试过选择更新、显式锁定和建议锁定,但它们都会在连接关闭时释放,这是正确的

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


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

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

  • 使用悲观锁定,所有操作都发生在单个数据库事务中。你
    选择。。。对于更新
    ,您可以通过提交事务来释放锁

    如果整个操作很短(没有用户交互!),尤其是在冲突可能性很高的情况下,悲观锁定是好的

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

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


您的用例不清楚。如果要锁定行的时间长于数据库连接,如何确保行不会永远留在原地?如何确定谁可以调用
updatea\u data
,谁被锁定?请详细描述你的目标。在我看来,这不像是“经典的选择更新问题”。我试图在@LaurenzAlbe更好地传达我的意图。检查问题now@LaurenzAlbe我有没有办法不用写一个整块来获取数据、验证输入和更新数据呢?我不知道你说的整块是什么意思。也就是说,我知道什么是巨石,但我不知道它如何引用你的10行代码。也许我的基本意思是问我可以使用什么锁,连接不可知@LaurenzAlbe。答案可能是乐观的锁定我知道锁定。问题是要锁定,您需要处于同一事务中。我不知道最佳实践是什么,但如果你看得正确,我正在为选择和更新创建一个不同的连接。我这样做是为了方便测试,因为没有状态。如果我在构造函数中创建连接对象,我可能会有一个长时间的空闲连接。唯一的实际选择似乎是乐观锁定。唯一的问题是因为我需要保留全部或全部,我需要在发生冲突时重新运行我的业务逻辑我的问题更多的是如何在锁定不同连接时将业务逻辑与数据库分离,而不是如何以及在这种情况下使用哪个锁