Django models.py事务回滚/提交问题

Django models.py事务回滚/提交问题,django,transactions,models,Django,Transactions,Models,我阅读了有关事务的文档,但仍然有点不知道如何真正做到这一点。 假设我在models.py with methods中有类Book(name、content、left\u key、right\u key、level),它将书籍内容存储为嵌套集。我想使用的主要方法是 @transaction.commit_on_success def add_node(self,right,level): cursor = connection.cursor() cursor.execute("UP

我阅读了有关事务的文档,但仍然有点不知道如何真正做到这一点。 假设我在models.py with methods中有类Book(name、content、left\u key、right\u key、level),它将书籍内容存储为嵌套集。我想使用的主要方法是

@transaction.commit_on_success
def add_node(self,right,level):
    cursor = connection.cursor()
    cursor.execute("UPDATE cms_Book  SET left_key = left_key + 2, right_key = right_key + 2 WHERE left_key > %s",[right])
    cursor.execute("UPDATE cms_Book SET right_key = right_key + 2 WHERE right_key >= %s AND left_key < %s ",[right,right])
    cursor.execute("INSERT INTO cms_Book SET left_key = %s, right_key = %s + 1, level = %s + 1, content='roar'",[right,right,level])
我需要的是执行add_node方法中的所有操作,然后用check方法检查逻辑是否中断,如果没有,则提交所有内容,否则回滚。我有点不明白的是,如果我使用try-except块,我需要db生成某种错误/异常,但它不会,例如:

   if (check_my_table_for_all_different_keys == none):
           transactions.commit
   else:
           transactions.rollback

检查我的表格中是否有所有不同的键-如果所有键都是唯一的,则不返回任何内容,否则返回相同或具有相同键的对象的id。此外,我也不确定如果我的if-else结构的逻辑是正确的(我认为是不正确的),那么part在提交所有3个事务时应该是什么样子的

上的django文档显示了两种可能的方法。这些示例假设您有一个
有效的
函数(例如,您的
检查我的表中是否有所有不同的键
),该函数验证数据库的当前状态,当数据错误时返回false

在成功时使用
提交
(就像您当前所做的那样)

这样,一旦函数成功返回,就会提交挂起的事务。当引发异常时,将回滚该异常

@transaction.commit_on_success
def add_node(self, right, level):
  # insert/update entries
  if not valid():
      raise Exception('invalid state')
调用代码需要处理此异常,但知道节点是否已成功添加

使用
手动提交

这更加明确,在适当的时候,您必须提交或回滚。你的例子正朝着这个方向发展

@transaction.commit_manually
def add_node(self, right, level):
  # insert/update entries
  if valid():
      transaction.commit()
  else:
      transaction.rollback()

未引发任何异常,“错误”被静默。如果一切正常,则事务已提交,否则将回滚。

上的django文档显示了两种可能的方式。这些示例假设您有一个
有效的
函数(例如,您的
检查我的表中是否有所有不同的键
),该函数验证数据库的当前状态,当数据错误时返回false

在成功时使用
提交
(就像您当前所做的那样)

这样,一旦函数成功返回,就会提交挂起的事务。当引发异常时,将回滚该异常

@transaction.commit_on_success
def add_node(self, right, level):
  # insert/update entries
  if not valid():
      raise Exception('invalid state')
调用代码需要处理此异常,但知道节点是否已成功添加

使用
手动提交

这更加明确,在适当的时候,您必须提交或回滚。你的例子正朝着这个方向发展

@transaction.commit_manually
def add_node(self, right, level):
  # insert/update entries
  if valid():
      transaction.commit()
  else:
      transaction.rollback()

未引发任何异常,“错误”被静默。如果一切正常,则事务已提交,否则将回滚。

现在一切正常。我想我应该提供一个完整的代码,如果有人会像我一样愚蠢并陷入困境=)。 因此,我们在models.py中有一本类书(名称、内容、左键、右键、级别),方法如下:

check_difference如果所有键都是唯一的,则返回false,否则返回true,因为包含相同键的所有对都被提取并放入q变量中。因此,如果返回任何内容,len(q)大于0

def检查_差异(自):
cursor=connection.cursor()
execute(“选择t1.id,COUNT(t1.id)作为rep,MAX(t3.right\u key)作为MAX\u right\
从作为t1的cms_书,作为t2的cms_书,作为t3的cms_书\
其中t1.左键t2.左键\
和t1。左键t2。右键\
和t1。右键t2。左键\
和t1。右键t2。右键\
按t1.id分组\
具有最大右SQRT(4*rep+1)+1”)
q=cursor.fetchall()
如果len(q)>0:
返回真值
其他:
返回错误
这里我执行3个查询,检查表的正确性,如果一切正常,所有键都是唯一的,check_difference返回false,然后提交所有查询并保存到数据库,否则回滚

@transaction.commit\u手动提交
def add_节点(自身、右侧、级别):
cursor=connection.cursor()
cursor.execute(“更新cms\u书集左\u键=左\u键+2,右\u键=右\u键+2,其中左\u键>%s”,[右])
游标。执行(“更新cms\u书集右键=右键+2,其中右键>=%s,左键<%s”,[right,right])
cursor.execute(“插入cms_Book SET left_key=%s,right_key=%s+1,level=%s+1,content='roar'”[right,right,level])
检查=自我检查差异()
如果check==True:
事务。回滚()
其他:
commit()事务

现在一切正常。我想我应该提供一个完整的代码,如果有人会像我一样愚蠢并陷入困境=)。 因此,我们在models.py中有一本类书(名称、内容、左键、右键、级别),方法如下:

check_difference如果所有键都是唯一的,则返回false,否则返回true,因为包含相同键的所有对都被提取并放入q变量中。因此,如果返回任何内容,len(q)大于0

def检查_差异(自):
cursor=connection.cursor()
execute(“选择t1.id,COUNT(t1.id)作为rep,MAX(t3.right\u key)作为MAX\u right\
从作为t1的cms_书,作为t2的cms_书,作为t3的cms_书\
其中t1.左键t2.左键\
和t1。左键t2。右键\
和t1。右键t2。左键\
和t1。右键t2。右键\
按t1.id分组\
具有最大右SQRT(4*rep+1)+1”)
q=cursor.fetchall()
如果len(q)>0:
返回真值
其他:
返回错误
<
@transaction.commit_manually
def add_node(self,right,level):
    cursor = connection.cursor()
    cursor.execute("UPDATE cms_Book  SET left_key = left_key + 2, right_key = right_key + 2 WHERE left_key > %s",[right])

    cursor.execute("UPDATE cms_Book SET right_key = right_key + 2 WHERE right_key >= %s AND left_key < %s ",[right,right])

    cursor.execute("INSERT INTO cms_Book SET left_key = %s, right_key = %s + 1, level = %s + 1, content='roar'",[right,right,level])
    check = self.check_difference()
    if check == True:
        transaction.rollback()
    else:
        transaction.commit()
from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()