我需要在Django 1.6中提交事务吗?

时间:2014-09-04 02:24:29

标签: django

我想创建和对象,将其保存到DB,然后检查DB上是否有另一行,token execution_time = 0。如果有,我想删除创建的对象,然后重新启动该过程。

transfer = Transfer(token = generateToken(size=9))
transfer.save()
while (len(Transfer.objects.filter(token=transfer.token, execution_time=0))!=1):
    transfer.delete()
    transfer = Transfer(token = generateToken(size=9))
    transfer.save()

我是否需要在每个循环之间提交事务?例如,在每个循环结束时调用commit()

while (len(Transfer.objects.filter(token=transfer.token, execution_time=0))!=1):
    transfer.delete()
    transfer = Transfer(token = generateToken(size=9))
    transfer.save()
    commit()

@transaction.commit_manually
def commit():
    transaction.commit()

2 个答案:

答案 0 :(得分:0)

根据您的描述,我认为您不需要使用交易。您基本上是使用代码手动重新创建事务回滚。

我认为处理此问题的最佳方法是让数据库约束强制执行此问题。 tokenexecution_time应该是唯一的吗?在这种情况下,您可以使用unique_together在Django中定义约束。如果约束是tokenexecution_time0时应该是唯一的,那么某些数据库也允许您定义类似的约束。

如果约束在数据库中,您可以在循环中执行get_or_create(),直到Transfercreated

如果由于某种原因无法在数据库中定义约束,那么我认为您的版本可以正常工作。 (一个改进是使用.count()而不是len。)

答案 1 :(得分:0)

  

我想创建和对象,将其保存到DB,然后检查是否存在   DB上的另一行,具有相同的令牌,执行时间= 0。如果   有,我想删除创建的对象然后重新启动   过程

根据您的最终目标,您可以采用几种方法:

  1. 您是否希望在编写时不会写入其他记录(以防止重复?)如果是这样,您需要锁定表,并且为此,您需要执行原子交易,@transaction.atomic(1.6中的新内容)

  2. 如果要确保在给定字段组合的情况下不创建重复记录,则需要在数据库级别使用unique_together

  3. 强制执行此操作

    我相信结合上述两个可以解决你的问题;但是,如果你想要更强力的方法;您可以覆盖对象的save()方法,然后在尝试创建(或更新)违反约束的记录时引发相应的异常。

    在您的视图中,您将捕获此异常,然后采取适当的操作。