我有一个复杂的代码块来处理ORM对象关系的创建/更新。
假设模型是A和B,关联是OneToOne A - B
(A.b_line
指向B)。
1)在创建/更新关联之前,需要更新一些A对象并将其保存到db中。在此操作期间,计算并保存A对象的一些内部字段。
2)更新的A对象从db重新加载(因为我们需要派生的计算字段),并且可以继续与B对象的关联。
示例:
def update_and_associate(a_items):
with transaction.atomic():
for item in a_items:
item.field_alpha = 1
# updates item.field_beta depending on
# item.field_alpha
item.update_beta()
item.save() # Save to db
with transaction.atomic:
for item in a_items:
item.refresh_from_db()
b = item.b_line
b.total = a.field_beta
b.save()
# later...
try:
update_and_associate(items)
except Exception as e:
handle_exception(e)
我将代码放在嵌套的原子事务块中,这样如果发生任何异常,应该回滚更改(MySql with InnoDB)。
问题是在第二个原子块中,当我用refresh_from_db
重新加载项时,它们不同步,这意味着它们具有旧值,就像第一个事务块根本没有运行一样。
我认为任何更改都会尽快进行,但我们仍有可能在例外的情况下回滚。
所以我的问题是:通过将代码括在transaction.atomic
中意味着要对数据库执行的所有写入修改都会推迟到我们退出块之后?这可以解释为什么来自db的刷新项目具有旧值。