yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

    • web基础

    • django框架脑图(!必看)

    • django简介
    • MVC及MTV设计模式
    • 搭建django项目环境
    • url路由
    • view视图
    • 模板语法
    • 模型ORM

      • 模型ORM简介
      • 模型和字段(1)
      • 模型和字段(2)
      • 多对多中间表详解
      • 模型的继承
      • 模型的元数据Meta
      • ORM单表增删改查
      • ORM多表增删改查
      • ORM中的事务和锁
        • 1. 事务
        • 2. 锁
          • 2.1 行级锁
          • 2.2 表锁
      • 验证器
    • 中间件
    • cookie,session
    • Form和modelform校验器、同源和跨域问题
    • 文件处理

    • django-websocket

    • django测试

    • django-项目

  • django-DRF

  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • django
  • 模型ORM
YiZhang-You
2023-05-18
目录

ORM中的事务和锁

# 1. 事务

事务要确保原子性

"""
事务
    ACID
        原子性:不可分隔的最小单位
        一致性:跟原子性是相辅相成
        隔离性:事务之间相互不干扰
        持久性:事务一旦确认永久生效

    事务的回滚
        rollback
    事务的确认
        commit
"""
# 目前是需要
from django.db import transaction

with transaction.atomic(): 开启事务
    # sql1
    # sql2
    # 的with代码块中写的所有orm操作都是属于同一个事务
print("执行其他操作")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")

import django

django.setup()

from app01 import models

from django.db import transaction
from django.db.models import F, Q

# 事务要确保原子性
# 原子性:一个原子事务要么完整执行,要么干脆不执行。这意味着,工作单元中的每项任务都必须正确执行。如果有任一任务执行失败,则整个工作单元或事务就会被终止。
try:
    with transaction.atomic(): # 开启事务
        # 一系列的操作
        models.Book.objects.all().update(kucun=F("kucun") - 10)
        models.Book.objects.all().update(sale=F("sale") + 10)
except Exception as e:
    print(e)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

下面再说一些设置事务的小原则吧:

1.保持事务短小     2.尽量避免事务中rollback     3.尽量避免savepoint     4.默认情况下,依赖于悲观锁     5.为吞吐量要求苛刻的事务考虑乐观锁     6.显示声明打开事务     7.锁的行越少越好,锁的时间越短越好

# 2. 锁

# 2.1 行级锁

entries = Entry.objects.select_for_update().filter(author=request.user)  #加互斥锁,由于mysql在查询时自动加的是共享锁,所以我们可以手动加上互斥锁。create、update、delete操作时,mysql自动加行级互斥锁

SELECT * FROM t1 WHERE id=1 FOR UPDATE;
model.T1.objects.select_for_update().filter(id=1)
1
2
3
4

# 2.2 表锁

class LockingManager(models.Manager):
    """ Add lock/unlock functionality to manager.
Example::

    class Job(models.Model): #其实不用这么负载,直接在orm创建表的时候,给这个表定义一个lock和unlock方法,借助django提供的connection模块来发送锁表的原生sql语句和解锁的原生sql语句就可以了,不用外层的这个LckingManager(model.Manager)类

        manager = LockingManager()

        counter = models.IntegerField(null=True, default=0)

        @staticmethod
        def do_atomic_update(job_id)
            ''' Updates job integer, keeping it below 5 '''
            try:
                # Ensure only one HTTP request can do this update at once.
                Job.objects.lock()

                job = Job.object.get(id=job_id)
                # If we don't lock the tables two simultanous
                # requests might both increase the counter
                # going over 5
                if job.counter < 5:
                    job.counter += 1
                    job.save()

            finally:
                Job.objects.unlock()
"""

def lock(self):
    """ Lock table.

    Locks the object model table so that atomic update is possible.
    Simulatenous database access request pend until the lock is unlock()'ed.

    Note: If you need to lock multiple tables, you need to do lock them
    all in one SQL clause and this function is not enough. To avoid
    dead lock, all tables must be locked in the same order.

    See http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
    """
    cursor = connection.cursor()
    table = self.model._meta.db_table
    logger.debug("Locking table %s" % table)
    cursor.execute("LOCK TABLES %s WRITE" % table)
    row = cursor.fetchone()
    return row

def unlock(self):
    """ Unlock the table. """
    cursor = connection.cursor()
    table = self.model._meta.db_table
    cursor.execute("UNLOCK TABLES")
    row = cursor.fetchone()
    return row
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
编辑 (opens new window)
ORM多表增删改查
验证器

← ORM多表增删改查 验证器→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式