mysql开启事务和加锁(django)

0. 事务介绍:

就是MySQL中的一种机制,你可以把它看成一种批量操作,它具有同时成功,同时失败的特性,其中只要一个失败了,全部回滚。

一:django中开启事务

a. 导入模块

from django.db import transaction

b. 使用(存储错误回滚)

with transaction.atomic():
    pass

c. 逻辑错误回滚

sid = transaction.savepoint()
if 1>2:
    transaction.savepoint_rollback(sid)

案例

from api import models
from django.db.models import F
from django.db import transaction


def add_hot(table, pk, formula):
    """热度增加"""
    with transaction.atomic():
        # 逻辑错误回滚
        sid = transaction.savepoint()
        try:
            table.objects.filter(id=pk).update(hot=F('hot') * formula)
        except:
            transaction.savepoint_rollback(sid)
            return '热度增加失败'

二:加锁

介绍

select_for_update():从机制来看属于悲观锁,同一时间,只能一个进来,从粒度来看本质是行锁

必须写在增删查改之后,不然报错

案例

with transaction.atomic():
            item_id = self.request.GET.get('item')
            price = int(self.request.data.get('price'))
            # 加悲观锁,同一时间,只能一个进来,其本质是行锁   select_for_update
            # 如果一开始没有价格会报错
            price_query = models.BidRecord.objects.filter(status=1, is_delete=False, is_show=True,
                                                          item_id=item_id).select_for_update()
            old_price = price_query.aggregate(max_price=Max('price')).get('max_price')
            if not old_price:
                serializer.save(user=self.request.user, item_id=item_id)
            if price < old_price:
                raise exceptions.ValidationError('当前价格低于最高价格')
            serializer.save(user=self.request.user, item_id=item_id)
            # 添加拍卖场的出价记录
            # 获取到拍卖场
            # 进行出价记录修改
            auction_query = models.AuctionItem.objects.filter(is_show=True, is_delete=False, status=3, id=item_id)
            auction_obj = auction_query.first().auction
            auction_obj.bid_count += 1
            # print('auction_obj.bid_count', auction_obj.bid_count)
            auction_obj.save()
            # 添加商品的出价记录
            # 获取到当前商品
            # 进行出价记录修改
            auction_query.update(
                bid_count=F('bid_count') + 1)

你可能感兴趣的:(mysql,django,mysql,python)