Tôi tin rằng câu trả lời của @ AnujGupta là chính xác. Tuy nhiên, việc rollback có thể tự đưa ra một ngoại lệ mà bạn nên nắm bắt và xử lý:
from django.db import transaction, DatabaseError
try:
a.save()
except DatabaseError:
try:
transaction.rollback()
except transaction.TransactionManagementError:
# Log or handle otherwise
Nếu bạn thấy bạn đang viết lại mã này ở nhiều save()
vị trí khác nhau , bạn có thể trích xuất phương thức:
import traceback
def try_rolling_back():
try:
transaction.rollback()
log.warning('rolled back') # example handling
except transaction.TransactionManagementError:
log.exception(traceback.format_exc()) # example handling
Cuối cùng, bạn có thể làm đẹp nó bằng cách sử dụng một công cụ trang trí bảo vệ các phương thức sử dụng save()
:
from functools import wraps
def try_rolling_back_on_exception(fn):
@wraps(fn)
def wrapped(*args, **kwargs):
try:
return fn(*args, **kwargs)
except:
traceback.print_exc()
try_rolling_back()
return wrapped
@try_rolling_back_on_exception
def some_saving_method():
# ...
model.save()
# ...
Ngay cả khi bạn triển khai trình trang trí ở trên, vẫn thuận tiện để giữ try_rolling_back()
như một phương pháp trích xuất trong trường hợp bạn cần sử dụng thủ công cho các trường hợp cần xử lý cụ thể và xử lý trang trí chung là không đủ.