Hãy xem xét ví dụ đơn giản này:Làm việc với lồng nhau @ transaction.commit_on_success trong Django
# a bank account class
class Account:
@transaction.commit_on_success
def withdraw(self, amount):
# code to withdraw money from the account
@transaction.commit_on_success
def add(self, amount):
# code to add money to the account
# somewhere else
@transaction.commit_on_success
def makeMoneyTransaction(src_account, dst_account, amount):
src_account.withdraw(amount)
dst_account.add(amount)
(lấy từ https://code.djangoproject.com/ticket/2227)
Nếu một ngoại lệ tăng trong Account.add()
, giao dịch trong Account.withdraw()
vẫn sẽ được cam kết và tiền bạc sẽ bị mất, bởi vì Django hiện không xử lý các giao dịch lồng nhau.
Không áp dụng bản vá cho Django, làm cách nào để đảm bảo rằng cam kết được gửi đến cơ sở dữ liệu, nhưng chỉ khi chức năng chính bên dưới trang trí @transaction.commit_on_success
kết thúc mà không làm tăng ngoại lệ?
Tôi đã xem đoạn mã này: http://djangosnippets.org/snippets/1343/ và có vẻ như nó có thể thực hiện công việc. Có bất kỳ hạn chế nào tôi nên biết nếu tôi sử dụng nó?
Rất cảm ơn trước nếu bạn có thể trợ giúp.
P.S. Tôi đang sao chép đoạn mã được trích dẫn trước đây cho mục đích hiển thị:
def nested_commit_on_success(func):
"""Like commit_on_success, but doesn't commit existing transactions.
This decorator is used to run a function within the scope of a
database transaction, committing the transaction on success and
rolling it back if an exception occurs.
Unlike the standard transaction.commit_on_success decorator, this
version first checks whether a transaction is already active. If so
then it doesn't perform any commits or rollbacks, leaving that up to
whoever is managing the active transaction.
"""
commit_on_success = transaction.commit_on_success(func)
def _nested_commit_on_success(*args, **kwds):
if transaction.is_managed():
return func(*args,**kwds)
else:
return commit_on_success(*args,**kwds)
return transaction.wraps(func)(_nested_commit_on_success)
Tôi thậm chí không chắc chắn đoạn mã này sẽ hoạt động. Nó có vẻ là 4 tuổi bây giờ, và ai đó đang nói rằng nó không hoạt động ở đây: http://djangosnippets.org/snippets/2515/ – alexpirine