我正在Python/Django应用程序上重构一些遗留代码,我正在寻找关于在SQL数据库上执行操作的样式/最佳实践建议。
现在,我正在尝试重做以下代码:
def fun():
try:
with transaction.atomic():
# query DB
# do business logic
# update DB entries with new values
except:
# handle exception问题是,在我的查询和更新之间有相当多的业务逻辑。但是,我觉得在另一个缩进/即定义为DB事务的一部分下抛出额外的代码是没有意义的。理想情况下,我想把它清理干净,只执行某些原子化的操作。我想它实际上不会减少我的代码行,但是我很好奇transaction.atomic()到底在做什么?
根据我对原子性的理解,读取实际上并不会影响数据存储的状态,因此我并不完全确定初始读取是否属于atomic()。
提前谢谢。
发布于 2020-09-07 04:26:43
如果读取只是普通的SELECT语句,并且使用默认的READ COMMITTED事务隔离级别,并且更新是单个READ COMMITTED语句,则是正确的。
但是:
如果有多个数据修改语句(例如,在多个表中修改行),则必须使用事务,以便永远不会执行这些语句中的一个。
在这种情况下,最好在修改数据之前启动事务。
具有事务隔离级别或更高级别的
SELECT语句,因为数据库的“快照”(应用于事务的数据库的状态)是在执行事务中的第一个SQL语句时获取的。您想要您的SELECT.,因此可以看到与您的UPDATE相同的数据库状态。
如果
FOR UPDATE子句,则实际上锁定表行以防止并发修改。在这种情况下,您需要在与数据修改相同的事务中释放SELECT,因为当事务结束时会释放锁。总之,最好保持数据库事务尽可能短。这降低了死锁的风险,并使模式更改无痛。
https://stackoverflow.com/questions/63770672
复制相似问题