用于方法相关事务的Django原子事务

时间:2016-06-19 15:08:01

标签: django transactions

考虑我的库应用程序中的util类有一个保存方法。在自定义utils.py

def update_book_count(key):
    key_to_update = BookConfig.objects.get(key=key)
    """
    returns {'key': 'Chemistry-700', 'count': 15}
    """
    key_to_update.count = key_to_update.count + 1
    key_to_update.save()

forms.py中考虑此代码:

class AddBookForm(forms.Form):
    #some fields

    def save(self):
        title = self.cleaned_data.get('title')
        category = self.cleaned_data.get('category') #Chemistry

        try:
            with transaction.atomic():
                book = Book(title=title, category=category)
                book.save(force_insert=True, force_update=False)
                update_book_count(category)
                #Say just for this case, I find reservations for this title
                loan = Loan.objects.filter(
                title=title,status="PENDING_BOOK_PURCHASE")
                loan.update(status="PENDING_MEMBER_COLLECTION")
        except IntegrityError:
            print("Atomic Txn Error")

我的问题是:atomic()是否扩展到update_book_count方法中的数据库事务?具体做法是:

  1. 如果update_book_count方法失败,book.save()交易是否也会被回滚?
  2. 如果loan.update()方法失败,update_book_count是否也会回滚?

1 个答案:

答案 0 :(得分:1)

首先,回答你的问题:

  1. 如果异常冒出并超出with语句(将查看您的代码),那么是,该事务将被回滚。

  2. 是的,当回滚交易时,到目前为止发生的所有事情都将被撤消。

  3. 顺便说一句,您应该使用信号自动更新这些计数字段,这样您就不必担心忘记手动调用该方法(和以前一样,如果在一个内部运行,这将由事务覆盖)。当删除对象时,你可以获得额外的好处。

    from django.db.models.signals import post_save, post_delete
    from django.dispatch import receiver
    from django.db import transaction
    
    @receiver(post_save, sender=Book)
    @receiver(post_delete, sender=Book)
    @transaction.atomic
    def _update_count(sender, instance, using, **kwargs):
        # get total number of books with this category
        count = Book.objects.filter(category=instance.category).count()
    
        # update the denormalized data
        BookConfig.objects.filter(key=instance.category).update(count=count)
    

    Django signal documentation