• Django中-事务操作


    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中发生问题的事实。这样可能会造成非预期的行为。

  • 相关阅读:
    async await异步方法的理解
    前端读取excel
    js如何实现上拉加载更多
    浅谈控制反转与依赖注入
    Java实现二叉树和遍历
    Linux生产故障排查
    排序算法之快速排序
    排序算法之堆排序
    树和二叉树知识整理
    常用的数据结构简单整理
  • 原文地址:https://www.cnblogs.com/hanbowen/p/10065551.html
Copyright © 2020-2023  润新知