您的位置:首页 > 编程语言 > Python开发

python之Django的入门08------事务管理、悲观锁、乐观锁

2018-10-19 19:50 411 查看

上一篇文章链接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})
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: