假设我使用app1.models.ModelOne
装饰的保存定义了模型@commit_on_success
。 ModelOne.save()
中捕获的所有异常都会重新引发。在model_one_instance.save()
上正常工作。
但是,在app2
中,我需要对ModelOne
进行一系列插入,并在其中任何一个失败时回滚所有这些内容。我该如何做到这一点?
使用app2.jobs.do_the_inserts
装饰@commit_on_success
无效。
答案 0 :(得分:4)
嵌套事务是特定于数据库的,因此您将失去可移植性。如果您需要,我会考虑做的是更改简单的@commit_on_save以获得更灵活的内容:
def save(commit=True):
if commit:
db.start_transaction()
try:
self.real_save()
db.commit_transaction()
except backend.DatabaseError, e:
db.rollback_transaction()
raise e
else:
self.real_save()
否则,您可以运行任意SQL命令,这样您就可以使用后端数据库使用的任何内容调用db.connection.cursor().execute()
,可能需要检查不对其他后端执行任何操作,这样您仍然可以使用sqlite进行本地测试。
根据您的应用结构,也可以使用savepoints。我写了一些实用程序,它们做了类似的事情:
答案 1 :(得分:0)
根据您的DBMS服务器,可能根本不支持嵌套事务。在DBMS中正确实现嵌套事务实际上非常困难,因为最终必须在事务之间共享锁。
但是,您所描述的内容听起来并不像嵌套交易。我不知道django是否支持XA事务,但您所描述的内容可以通过TP监视器体系结构和XA感知DBMS实现(现在大部分都是这样)。
如果您的平台不支持XA事务,则必须对事务进行结构化,以便将存储它们的记录存储在某处。 Fowler的企业应用程序架构模式中描述的“工作单元”模式的某些方面可能为这种子系统的体系结构提供了良好的开端。