Django中-事務操作


如何在Django中進行事務操作呢?

近期,公司里要使用Django開發一套金融相關的系統。

涉及錢了.....安全安全安全

如果錢轉到一半,系統崩了,咋辦?

如果錢匯到一半,系統崩了,咋辦?

如果東西買到一半,系統崩了,咋辦?

我錢轉到一半,錢已經從我的賬戶扣除了,但是,服務出問題了,當掉了,這條任務執行到一半停掉了,那我的錢呢???

這就會造成嚴重的損失?

怎么辦?

還記得在Mysql數據庫中的原子操作嗎?

不記得??!!!

好吧,我告訴你。

客戶A要給客戶B轉一筆錢,這個在數據庫中需要進行兩步:

  1.客戶A減錢

  2.客戶B加錢

如果在第一步結束后,服務器出現異常,停下了,第二步沒有進行,如果數據庫使用了事務操作,真的出現異常的時候,前面的操作會進行回滾。

簡單的說就是:要么全部執行成功,要么一個都不執行

這個回滾的操作就叫做數據庫的原子性操作。

但是啊,這是在MySQL數據庫中,我們在Django的ORM中如何進行呢?


首先,我們要導入一個Django的內置模塊

from django.db import transaction

 

接着,就可以使用了

from django.db import transaction

with transaction.atomic():
    //ORM操作
    pass

 

 

我們舉個例子測試一下

1.創建一個項目,新建一個APP(基礎操作,這里不再贅述)

2.通過ORM創建生成表

from django.db import models

class UserInfo(models.Model):
    username = models.CharField("用戶",max_length=32)
    balance = models.CharField("余額",max_length=32)

 

注意啊:踩過的坑,涉及金融計算,涉及小數啊,要求特別精確的,我們用字符串存儲。

如果是金融計算的話,我們用一個decimal來進行計算。

3.我們給數據庫加兩條數據,用來模擬兩個用戶之間的轉賬

4.配置URL

5.創建對應的視圖函數

from django.shortcuts import render,HttpResponse
from app01 import models
from django.db import transaction
from django.db.models import F

def index(request):
    try:
        with transaction.atomic():
            models.UserInfo.object.filter(id=1).update(balance=F("balance")-100)
models.UserInfo.object.filter(id
=2).update(balance=F("balance")+100) except Exception as e: return HttpResponse("出現錯誤<%s>"%str(e)) return HttpResponse("執行成功")

 

當我們訪問index的時候,會進行一次轉賬操作

6.現在,我們讓他報錯

from django.shortcuts import render,HttpResponse
from app01 import models
from django.db import transaction
from django.db.models import F

def index(request):
    try:
        with transaction.atomic():
            models.UserInfo.object.filter(id=1).update(balance=F("balance")-100)
            raise 一個錯誤
            models.UserInfo.object.filter(id=2).update(balance=F("balance")+100)
    except Exception as e:
        return HttpResponse("出現錯誤<%s>"%str(e))
    return HttpResponse("執行成功")

 

我們再次查看數據庫文件,如果沒有數據的原子性操作,我們第一條sql執行完報錯,那錢肯定是減去了

但是,我們進行的是原子性的操作,你會發現錢沒有減誒。

完美,沒毛病


 

這是常規的一種操作,另外還有一起其他的方式

對整個view視圖開啟事務

from django.db import transaction

@transaction.atomic
def index(request):
    //ORM操作
    return ....

注意在原子塊中不要進行錯誤捕獲

當退出原子塊的時候,Django會去查看它是否正常退出或者是否有異常來確定是否提交或者回滾

如果你捕獲並處理了原子塊中的異常,可能會隱藏Django中發生問題的事實。這樣可能會造成非預期的行為。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM