悲观锁
上一篇文章链接Django07
我们接着上一篇文章的基础上,来继续了解进一步的Django框架
一.事务管理
在实际项目里,事务管理是一个很重要的内容。 他可以保证一系列类操作要不全部成功要不全部失败。也可以保证当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。
特性:
原子性:一组操作,要么成功,要么撤回
稳定性:有非法数据,事务撤回,比如外键连接
隔离性:事务是独立运行的,一个事务的处理结果,影响了其他事务,其他事务会撤回
可靠性:当出现软件或者硬件崩溃的情况,数据表会驱动日志文件进行重构修改
事务管理语句:
1.开启一个事务管理
begin
2.提交操作,对于数据库的操作是永久性的
commit / commit work
3.回滚会撤销所有未被提交的操作
rollback / rollback work
事务的隔离级别:
1.读取未被提交的内容(脏读) read uncommitted
2.读取提交的内容(数据库默认的隔离级别) read committed
3.可重复读(易引起幻读)
4.可串行:最高级别,强制事务排序(本质是在每一个读的数据行上加共享锁,可能会带来大量的超时现象和锁竞争)
二、乐观锁
总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改
三、悲观锁
总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁
四、例子
from django.db import transaction
'''悲观锁下订单(存在事务管理)'''
class TradeCommitView(View):
@transaction.atomic #装饰器的方法实现事务管理
def post(self,request):
'''设置保存点用于事务管理'''
sid1 = transaction.savepoint()
user = request.user
if not user.is_authenticated():
'''判断是否登陆'''
return redirect(reverse('car:index'))
# 接收数据
car_id = request.POST.get('car_id')
pay_method = request.POST.get('pay_style')
address_id = request.POST.get('address')
from datetime import datetime
order_id = str(user.id) + datetime.now().strftime('%Y%m%d%H%M%S')
# 运费(元)
transport = 5000
if not all([car_id,pay_method,address_id]):
return Jsonresponse({'errmsg':'数据内容不完整'})
try:
# car = CarDetail.objects.get(id=car_id)
#悲观锁
car = CarDetail.objects.select_for_update().get(id=car_id)
except:
transaction.savepoint_rollback(sid1)
return HttpResponse('车辆不存在')
service = float(car.car_price) * 10000 * 0.04
if service < 3000:
service = 3000
add = AddressInfo.objects.get(id=address_id)
# sid1 = transaction.savepoint()
#创建订单
try:
order_new = OrderInfo.objects.create(
order_id = order_id,
user = user,
add = add,
price = car.car_price,
service_charge =service,
freight =transport,
# status = 0,
# pay_method =
online_pai_method = pay_method
)
import time
# time.sleep(30)
if car.status != 1: #如果车辆不是上线状态
transaction.savepoint_rollback(sid1) #回退到保存点
return JsonResponse({'errmsg':'下单失败'})
order_car =OrderCar.objects.create(
oder=order_new,
car_id = car,
comment='')
car.status = 0
car.save()
except Exception as e:
transaction.savepoint_rollback(sid1)
return JsonResponse({'errmsg':e})
transaction.savepoint_commit(sid1)
return HttpResponse('结束')
'''乐观锁下订单(存在事务管理)'''
class TradeCommitView_le(View):
@transaction.atomic
def post(self, request):
'''设置保存点用于事务管理'''
sid1 = transaction.savepoint()
user = request.user
if not user.is_authenticated():
'''判断是否登陆'''
return redirect(reverse('car:index'))
# 接收数据
car_id = request.POST.get('car_id')
pay_method = request.POST.get('pay_style')
address_id = request.POST.get('address')
from datetime import datetime
order_id = str(user.id) + datetime.now().strftime('%Y%m%d%H%M%S')
# 运费(元)
transport = 5000
if not all([car_id, pay_method, address_id]):
return HttpResponse('数据内容不完整')
# 校验数据的正确(作业)
try:
car = CarDetail.objects.get(id=car_id)
except:
pass
service = float(car.car_price) * 10000 * 0.04
if service < 3000:
service = 3000
add = AddressInfo.objects.get(id=address_id)
# sid1 = transaction.savepoint()
# 创建订单
try:
order_new = OrderInfo.objects.create(
order_id=order_id,
user=user,
add=add,
price=car.car_price,
service_charge=service,
freight=transport,
# status = 0,
# pay_method =
online_pai_method=pay_method
)
#乐观锁。不是真正意思上的锁,只是在更新前查询,如果不符合条件就回滚,符合就继续执行。
res = CarDetail.objects.filter(id=car_id,status=1).update(status=0)
print('res',res)
if res == 0 :
transaction.savepoint_rollback(sid1)
return HttpResponse('车辆不存在')
order_car = OrderCar.objects.create(
oder=order_new,
car_id=car,
comment='')
except Exception as e:
transaction.savepoint_rollback(sid1)
return JsonResponse({'errmsg': e})
transaction.savepoint_commit(sid1)
return render(request,'trade_pay.html',context={'order_id':order_id})
文章最后发布于: 2018-10-19 19:50:38
相关阅读
死锁(DeadLock) 死锁概述 线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于synchronized的特性,一个线程持有一个资源
1月22日,腾讯QQ正式公布2019新春活动——“福气'袋'回家”。在中国人的年俗文化里,习惯通过各种仪式感讨个好
我们有时在编辑Excel表格的时候,想对表格中的某些单元格保护起来,不让别人随意修改,怎么办呢?今天,seo实验室小编就教大家在Excel中锁
java-多线程-CountDownLatch(闭锁) CyclicBarrier(栅
(代码来源网络共享) 这几个工具类其实说白了就是为了能够更好控制线程之间的通讯问题~ CountDownLatch 是一个同步的辅助类,允许
如今的时装周已不仅仅是服饰界的盛典,更是为明年的整体流行趋势设立指向标。而在刚刚过去的2020春夏时装周上,从全新服饰到出席嘉宾