Django4.0 數據庫事務-底層API

2022-03-16 17:38 更新

自動提交

Django 在 ?django.db.transaction? 模塊中提供了一個 API 來管理每個數據庫連接的自動提交狀態(tài)。

get_autocommit(using=None)

set_autocommit(autocommit, using=None)

這些函數使接受一個 ?using ?參數表示所要操作的數據庫。如果未提供,則 Django 使用 "?default?" 數據庫。
自動提交默認為開啟,如果你將它關閉,自己承擔后果。
一旦你關閉了自動提交, Django 將無法幫助你,數據庫將會按照你使用的數據庫適配器的默認行為進行操作。
在關閉自動提交之前,你必須確保當前沒有活動的事務,通常你可以執(zhí)行 ?commit()? 或者 ?rollback()? 函數以達到該條件。
當一個原子 ?atomic()? 事務處于活動狀態(tài)時, Django 將會拒絕關閉自動提交的請求,因為這樣會破壞原子性。

事務

事務是指具有原子性的一系列數據庫操作。即使你的程序崩潰,數據庫也會確保這些操作要么全部完成要么全部都未執(zhí)行。

Django 不提供啟動事務的 API。 啟動事務的預期方法是使用 ?set_autocommit()? 禁用自動提交。

進入事務后,你可以選擇在 ?commit()? 之前應用執(zhí)行的更改,或者使用 ?rollback()? 取消它們。這些函數在 ?django.db.transaction? 中定義。

commit(using=None)

rollback(using=None)

這些函數使接受一個 ?using ?參數表示所要操作的數據庫。如果未提供,則 Django 使用 "?default?" 數據庫。
當一個原子 ?atomic()? 事務處于活動狀態(tài)時, Django 將會拒絕進行事務提交或者事務回滾,因為這樣會破壞原子性。

保存點

保存點在事務中是標記物,它可以使得回滾部分事務,而不是所有事務。 SQLite, PostgreSQL, Oracle, 和 MySQL (當使用 InnoDB 存儲引擎) 后端提供了保存點。其他后端提供了保存點函數,但它們是空操作——它們實際上沒有做任何事情。
如果你正在使用 Django 的默認行為——自動提交,保存點并不特別有用。盡管,一旦你用 ?atomic() ?打開了一個事務,那么需要構建一系列的等待提交或回滾的數據庫操作。如果發(fā)出回滾,那么會回滾整個事務。保存點有能力執(zhí)行顆粒度級別的回滾,而不是由 ?transaction.rollback()? 執(zhí)行的完全回滾。
當嵌套了 ?atomic()? 裝飾器,它會創(chuàng)建一個保存點來允許部分提交或回滾。強烈推薦只使用 ?atomic()? 而不是下面描述的函數,但它們仍然是公共 API 的一部分,而且沒計劃要棄用它們。
這里的每一個函數使用 ?using ?參數,這個參數為應用的數據庫名。如果沒有 ?using ?參數,那么會使用 "?default?" 數據庫。
保存點由 ?django.db.transaction?中的三個函數來控制:

savepoint(using=None)

創(chuàng)建新的保存點。這標志著事務中已知處于“良好”狀態(tài)的一個點。返回保存點ID (?sid?) 。

savepoint_commit(sid, using=None)

釋放保存點 ?sid ?。自保存點被創(chuàng)建依賴執(zhí)行的更改成為事務的一部分。

savepoint_rollback(sid, using=None)

回滾事務來保存 ?sid ?。

如果不支持保存點或數據庫在自動模式時,這些函數不執(zhí)行操作。

另外,還有一個實用功能:

clean_savepoints(using=None)

重置用于生成唯一保存點ID的計數器。

下面的例子演示保存點的用法:

from django.db import transaction

# open a transaction
@transaction.atomic
def viewfunc(request):

    a.save()
    # transaction now contains a.save()

    sid = transaction.savepoint()

    b.save()
    # transaction now contains a.save() and b.save()

    if want_to_keep_b:
        transaction.savepoint_commit(sid)
        # open transaction still contains a.save() and b.save()
    else:
        transaction.savepoint_rollback(sid)
        # open transaction now contains only a.save()

保存點可能通過執(zhí)行部分回滾來恢復數據庫錯誤。如果你在 ?atomic()? 塊中執(zhí)行此操作,那么整個塊將仍然被回滾,因為它不知道你已經處理了較低級別的情況。為了防止發(fā)生,你可以使用下面的函數控制回滾行為。

get_rollback(using=None)

set_rollback(rollback, using=None)

當存在內部原子塊時,設置回滾標記為 ?True ?將強制回滾。這對于觸發(fā)回滾而不引發(fā)異??赡芎苡杏谩?br>將它設置為 ?False ?會防止這樣的回滾。在這樣做之前,確保你已經將事務回滾到當前原子塊中一個正常的保存點。否則你會破壞原子性并且可能發(fā)生數據損壞。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號