• django后台使用MySQL情况下的事务控制详解


    写在前面:

      默认情况下django会把autocommit设置为“1”也就是说所针对数据库的每一次操作都会被做成“单独”的一个事务;这样的处理好处就在于它方便,

      在编程的时候可以少写一些代码,比如我们不用先“start transaction ” 操作完之后再“commit” 或 “rollback”。

    django对事务控制的实现方式:

      django中通过transaction.atomic()上下文来完成事务控制

        try:
            with transaction.atomic():
                # 对数据库的操作
        except Exception as e:
            # 异常处理
        
        #其它处理逻辑

    以学院式的银行转账业务为例:

      1):一张表示银行存款的表(为了突出事务控制在些不对表进行过多的设计)

    from django.db import models
    
    # Create your models here.
    
    class SavingCard(models.Model):
        name=models.CharField(max_length=64,default='',null=False)
        saving = models.DecimalField(max_digits=16,decimal_places=4,default=0,null=False)

      以上模型它所对应的SQL语句如下

    CREATE TABLE `bank_savingcard` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(64) NOT NULL,
      `saving` decimal(16,4) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8

      手工在数据库中插入两行测试数据

    insert into bank_savingcard(name,saving) values
          ('jianglexing',100),('welson',80);

      2):用django实现一个转账功能的view

    from django.shortcuts import render
    from .models import SavingCard
    from django.db import transaction
    from django.http import HttpResponse
    # Create your views here.
    
    def transfer(request,fromname,toname,count):
        """
        完整的转账功能
        """
    
        try:
            with transaction.atomic():
                if count < 0:
                    raise ValueError("转账资金不得小于0元")
                
                fromAccount = SavingCard.objects.get(name=fromname)
                toAccount   = SavingCard.objects.get(name=toname)
                if count > fromAccount.saving:
                    raise ValueError("转账资金不得大于卡内余额")
    
                fromAccount.saving=fromAccount.saving-count
                toAccount.saving = toAccount.saving + count
    
                fromAccount.save()
                toAccount.save()
        except Exception as e:
            return HttpResponse("<p>{} {}</p>".format("出现异常转账失败",e))
        return HttpResponse("转账成功")

      注册转账接口

    from django.contrib import admin
    from django.urls import path
    from bank.views import transfer
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('bank/<str:fromname>/transaction/<str:toname>/<int:count>/',transfer)
    ]

      3):调用转账接口

    http://127.0.0.1:8080/bank/jianglexing/transaction/welson/5/

      jianglexing转5元给welson

      4):转账前后数据库的内容变化

    select * from bank_savingcard;
    +----+-------------+----------+
    | id | name        | saving   |
    +----+-------------+----------+
    |  1 | jianglexing | 100.0000 |
    |  2 | welson      |  80.0000 |
    +----+-------------+----------+
    2 rows in set (0.00 sec)
    
     select * from bank_savingcard;
    +----+-------------+---------+
    | id | name        | saving  |
    +----+-------------+---------+
    |  1 | jianglexing | 95.0000 |
    |  2 | welson      | 85.0000 |
    +----+-------------+---------+
    2 rows in set (0.00 sec)

      5):强行转账1000元看一下

    http://127.0.0.1:8080/bank/jianglexing/transaction/welson/1000/

     

      前后的数据库内容对比

    select * from bank_savingcard;
    +----+-------------+---------+
    | id | name        | saving  |
    +----+-------------+---------+
    |  1 | jianglexing | 95.0000 |
    |  2 | welson      | 85.0000 |
    +----+-------------+---------+
    2 rows in set (0.00 sec)
    
    select * from bank_savingcard;
    +----+-------------+---------+
    | id | name        | saving  |
    +----+-------------+---------+
    |  1 | jianglexing | 95.0000 |
    |  2 | welson      | 85.0000 |
    +----+-------------+---------+
    2 rows in set (0.00 sec)

      6):强行转账1000到一个不存在的账号

     

    ----------------------------------------------------------------------------------------------

  • 相关阅读:
    屏幕截图(带光标)
    warning LNK4070的解决办法
    2015-08-10
    wmic的用法
    2015-03-12
    MFC Button控件自绘
    MFC窗口创建、销毁消息流程
    DDX_Control、SubclassWindow和SubclassDlgItem
    css animation fade in
    kohana reading session data error(session_start)引起的错误
  • 原文地址:https://www.cnblogs.com/JiangLe/p/8988894.html
Copyright © 2020-2023  润新知