zoukankan      html  css  js  c++  java
  • 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到一个不存在的账号

     

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

  • 相关阅读:
    Yield Usage Understanding
    Deadclock on calling async methond
    How to generate file name according to datetime in bat command
    Run Unit API Testing Which Was Distributed To Multiple Test Agents
    druid的关键参数+数据库连接池运行原理
    修改idea打开新窗口的默认配置
    spring boot -thymeleaf-url
    @pathvariable和@RequestParam的区别
    spring boot -thymeleaf-域对象操作
    spring boot -thymeleaf-遍历list和map
  • 原文地址:https://www.cnblogs.com/JiangLe/p/8988894.html
Copyright © 2011-2022 走看看