原子操作

举个例子:

A想要从自己的帐户中转1000块钱到B的帐户里。那个从A开始转帐,到转帐结束的这一个过程,称之为一个事务。在这个事务里,要做如下操作:

  •  1. 从A的帐户中减去1000块钱。如果A的帐户原来有3000块钱,现在就变成2000块钱了。
  •  2. 在B的帐户里加1000块钱。如果B的帐户如果原来有2000块钱,现在则变成3000块钱了。

如果在A的帐户已经减去了1000块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时B的帐户里还没有增加1000块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到A的帐户还没减1000块的状态,B的帐户的原来的状态。此时A的帐户仍然有3000块,B的帐户仍然有2000块。

我们把这种要么一起成功(A帐户成功减少1000,同时B帐户成功增加1000),要么一起失败(A帐户回到原来状态,B帐户也回到原来状态)的操作叫原子性操作。

如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性。

Django提供了一种简单的API去控制数据库的事务交易...原子操作用来定义数据库事务的属性。原子操作允许我们在数据库保证的前提下,创建一堆代码。如果这些代码被成功的执行,所对应的改变也会提交到数据库中。如果有异常发生,那么操作就会回滚。”
用法和上例一致,可以采用装饰器用法或代码块用法,推荐代码块。
def index(request):
    try:
        with transaction.atomic():
            work2()
    except Exception:
        pass

具体事例:

def post(self,request):
    if not request.user.is_authenticated():
        # 如果没有登录则跳转到登陆界面
        return redirect_to_login('request.get_full_path')
    # 通过getlist获取对应的checkbox类型的value,保存一个list类型的数据
    # 通过checkbox来获取提交的商品,勾选就提交,不勾选不提交
    #checkbox的name='cart_by_goods_id'
    cart_by_goods_ids = request.POST.getlist('cart_by_goods_id')
    #通过in_bulk,传入对应的id集合,则会返回对应的对象集合字典
    shopcarts = ShopCart.objects.in_bulk(id_list=cart_by_goods_ids)
    #数据验证,给多少id就要返回多少数据,否则说明购物车数据异常
    #assert用法:如果assert返回false则终止程序
    assert len(shopcarts.keys()) == len(cart_by_goods_ids)

    try:
        # 提交订单时实例化一个订单
        # 创建订单,要么全部成功,要么全部失败,因为该业务是一个原子操作
        # 使用transaction.atomic做事务,保证所有数据库操作保持原子性
        # 将需要进行原子操作的代码放到with transaction.atomic():里面
        with transaction.atomic():
            ordermain = OrderMain(uuid=uuid.uuid4(),user=request.user,total=0)
            ordermain.save()
            #遍历出所有商品
            total = 0
            for shopcart in shopcarts.values():
                orderdetail = OrderDetail()
                orderdetail.order = ordermain
                orderdetail.goods_info = shopcart.goodsinfo
                orderdetail.goods_price = float(shopcart.goodsinfo.price)
                if shopcart.buy_num > shopcart.goodsinfo.stock:
                    message = u'%s库存不足'% shopcart.goodsinfo.name
                    raise StockException,message
                orderdetail.count = shopcart.buy_num
                orderdetail.goods_total = float(shopcart.goodsinfo.price * shopcart.buy_num)
                total += orderdetail.goods_total
                orderdetail.save()
                #将购物车保存到订单后字典中要删除对应的购物车
                ShopCart.objects.filter(id=shopcart.id).delete()
            ordermain.total = total
            ordermain.save()
    except StockException,e:
        message = e
        cart_infos = ShopCart.objects.filter(user=request.user)
        return render(request,'shop_cart/cart.html',locals())
    #成功就跳转订单详情展示
    return redirect(reverse('shop_order:show_order',kwargs={'oid':ordermain.id}))

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值