day88_11_8,事务的隔离级别celery定时订单与项目整合。
一。事务的隔离级别。
mysql的默认数据库级别是可重复读,一般的应用使用的是读已提交
http://www.zsythink.net/archives/1233/
1. Read UnCommitted(读未提交)
最低的隔离级别。一个事务可以读取另一个事务并未提交的更新结果。
2. Read Committed(读提交)
大部分数据库采用的默认隔离级别。一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。
3. Repeatable Read(重复读)
mysql的默认级别。整个事务过程中,对同一笔数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否。
4. Serializable(序列化)
最高隔离级别。所有事务操作依次顺序执行。注意这会导致并发度下降,性能最差。通常会用其他并发级别加上相应的并发锁机制来取代它。
1.脏读。
当两个事务对数据进行操作时,事务A读取了一些数据之后,对其进行修改,但是还未提交,事务b对该数据进行读取的时候读取的是事务a修改后的数据,这个数据就是一个脏数据,如果数据a对该数据进行回滚,就会报错。
2.不可重复读
当事务A对一些数据进行读取的时候,事务B也对该数据进行了读取,并修改,当事务A再次对其进行读取的时候,就会发现数据不对,就是不可重复读。即数据不重复。
3。幻读。
在重复读的隔离级别下,数据是不能被修改的,但是可以被提交,所以当事务A对影响行数据进行读取的时候,事务b添加了一项数据,事务A再次读取的时候就会发现多了一条数据,就像出现幻觉一样。
处理方法:
1.悲观锁。
当事务处理数据的时候。默认所有的数据会被其他数据操作,所以加上锁,不开放任何权限(包括查的权限),保证所有数据都处理完再开放锁。
2。乐观锁,
当处理事务的时候,默认所有的数据不会被其他数据,再提交数据之前再进行判断库中的数据是否和一开始读的数据相同(需要再可重复读的级别下,再事务过程中,保证识别到其他操作的提交数据)。
在处理数据时,后提交的操作会时最终的数据。
二。celery
当订单提交完毕之后,用户不会马上支付,就会调用celery分配异步任务,将该任务延时一定时间,将其回滚到一开始的状态。
项目详情。
comment
def get_level(data):
data_list=[]
for item in data:
if item['parent_id']==0:
item['level']=0
else:
item['level']=1
data_list.append(item)
return data_list data=[
{"cat_id":1,"name":"北京","parent_id":0},
{"cat_id":2,"name":"上海","parent_id":0},
{"cat_id":3,"name":"沙河","parent_id":1},
{"cat_id":4,"name":"sb镇","parent_id":3},
{"cat_id":5,"name":"昌平","parent_id":1},
{"cat_id":6,"name":"青浦","parent_id":2},
] def get_tree(data):
lists=[]
tree={}
for i in data:
tree[i['cat_id']]=i
for item in data:
if not item['parent_id']:
lists.append(tree[item['cat_id']])
else:
if "children" not in tree[item['parent_id']]:
tree[item['parent_id']]['children']=[]
tree[item['parent_id']]['children'].append(tree[item['cat_id']])
return lists print(get_tree(data)) res=[]
def get_son(data,level=0,parent_id=0,is_clear=True):
if is_clear:
res.clear()
for item in data:
if item['parent_id']==parent_id:
item['level']=level
res.append(item)
get_son(data,level=level+1,parent_id=item['cat_id'],is_clear=False)
return res # print(get_son(data))
# son=get_son(data)
# for i in son:
# print("-"*i['level']+i['name'])
# 1北京 0
# 2-海淀1
# 4--sb镇2
# -昌平
# 3 上海 0
# -青浦
# --徐泾镇
# -闵行
res_id=[]
def get_son_id(data,parent_id=0,is_clear=True):
if is_clear:
res_id.clear()
if parent_id :
res_id.append(parent_id) for item in data:
if item['parent_id']==parent_id:
res_id.append(item['cat_id'])
get_son_id(data,parent_id=item['cat_id'],is_clear=False)
return res_id # print(get_son_id(data,1)) import time ,random
def get_order_id():
st="012345679qwertyui"
order_id=str(time.strftime("%Y%m%d%h%M%S"))+"".join(random.sample(st,5))
return order_id from datetime import datetime def add_task(order_id,seconds=5):
from pro_celery.celery import del_order
ctime = datetime.now()
utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
from datetime import timedelta
time_delay = timedelta(seconds=seconds)
task_time = utc_ctime + time_delay
result = del_order.apply_async(args=[order_id, ], eta=task_time)
func.py
my_ser
from rest_framework import serializers
from app01 import models
class Banner_ser(serializers.ModelSerializer):
image_url=serializers.ImageField(source="image.image_url")
product_id=serializers.IntegerField(source="product.product_id")
class Meta:
model=models.Banner
fields="__all__"
Banner_ser
from rest_framework import serializers
from app01 import models
class Category_ser(serializers.ModelSerializer):
image_url=serializers.ImageField(source="image.image_url")
parent_id=serializers.SerializerMethodField()
def get_parent_id(self,obj):
if obj.parent_id is None:
return 0
else:
return obj.parent_id class Meta:
model=models.Category
fields="__all__"
Category_ser
from rest_framework import serializers
from app01 import models
class Goods_ser(serializers.ModelSerializer):
image_url=serializers.ImageField(source="image.image_url")
stock=serializers.IntegerField(source="stock.quantity")
class Meta:
model=models.Product
fields="__all__"
Goods_ser
Pay
import time
from app01.wx import settings
class Wxpay:
def pay(self,order_data):
self.order_id = order_data["order_id"]
self.open_id = order_data['open_id']
self.ip = order_data['ip']
data_body = self.get_body_data()
import requests
url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
response = requests.post(url, data_body.encode("utf-8"), headers={'content-type': "application/xml"})
res_dict = self.xml_to_dic(response.content)
timeStamp = str(int(time.time()))
paySign = self.get_pay_sign(res_dict, timeStamp) data_dic = {
'timeStamp': timeStamp,
'nonceStr': res_dict['nonce_str'],
'package': f"prepay_id={res_dict['prepay_id']}",
'signType': 'MD5',
"paySign": paySign,
} return data_dic def get_pay_sign(self, res_dict, timeStamp):
data_dic = {
'appId': res_dict['appid'],
'timeStamp': timeStamp,
'nonceStr': res_dict['nonce_str'],
'package': f"prepay_id={res_dict['prepay_id']}",
"signType": "MD5"
}
sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
import hashlib
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign = md5.hexdigest()
return sign.upper() def xml_to_dic(self, xml_data):
import xml.etree.ElementTree as ET
'''
xml to dict
:param xml_data:
:return:
'''
xml_dict = {}
root = ET.fromstring(xml_data)
for child in root:
xml_dict[child.tag] = child.text
return xml_dict def get_random(self):
import random
data = "123456789zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP"
nonce_str = "".join(random.sample(data, 30))
return nonce_str def get_sign(self):
data_dic = {
"nonce_str": self.nonce_str,
"out_trade_no": self.out_trade_no,
"spbill_create_ip": self.spbill_create_ip,
"notify_url": self.notify_url,
"openid": self.open_id,
"body": self.body,
"trade_type": "JSAPI",
"appid": self.appid,
"total_fee": "",
"mch_id": self.mch_id
} sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)])
sign_str = f"{sign_str}&key={settings.pay_apikey}"
import hashlib
md5 = hashlib.md5()
md5.update(sign_str.encode("utf-8"))
sign = md5.hexdigest()
return sign.upper() def get_body_data(self):
self.appid = settings.AppId
# openid=self.open_id
self.mch_id = str(settings.pay_mchid)
self.nonce_str = self.get_random()
self.out_trade_no = self.order_id
self.spbill_create_ip = self.ip
self.notify_url = "https://www.test.com"
self.body = "lzx"
self.sign = self.get_sign()
body_data = f"""
<xml>
<appid>{self.appid}</appid>
<mch_id>{self.mch_id}</mch_id>
<nonce_str>{self.nonce_str}</nonce_str>
<sign>{self.sign}</sign>
<body>{self.body}</body>
<out_trade_no>{self.out_trade_no}</out_trade_no>
<total_fee>1</total_fee>
<spbill_create_ip>{ self.spbill_create_ip}</spbill_create_ip>
<notify_url>{self.notify_url}</notify_url>
<openid>{self.open_id}</openid>
<trade_type>JSAPI</trade_type>
</xml>"""
return body_data
Wxpay
views
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.my_ser import Banner_ser class List(APIView):
def post(self,request):
data = models.Banner.objects.filter(is_show=True).order_by("-w_order")
data = Banner_ser.Banner_ser(instance=data,many=True,context={"request":request}).data
return Response({
"code":200,
"msg":"ok",
"data":data
})
Banner
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.my_ser import Category_ser
from app01.comment import func
class All(APIView):
def post(self,request):
data=models.Category.objects.filter(is_show=True)
data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data
data=func.get_son(data)
return Response({
"code":200,
"msg":"ok",
"data":data
})
Category
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.my_ser import Goods_ser
from app01 import models
from app01.my_ser import Category_ser,Goods_ser
from app01.comment import func
class HotGoods(APIView):
def post(self,request):
data=models.Product.objects.filter(disabled=True).order_by("-buy_count","-w_order")
data=Goods_ser.Goods_ser(instance=data,many=True,context={"request":request}).data
return Response({"code":200,"msg":"ok","data":data}) class List(APIView):
def post(self,request):
param=request.data
if param.get('category_id'):
data=models.Category.objects.filter(is_show=True)
data=Category_ser.Category_ser(instance=data,many=True,context={"request":request}).data
all_id=func.get_son_id(data,param['category_id'])
data=models.Product.objects.filter(disabled=True,cat_id__in=all_id).order_by("-w_order")
data = Goods_ser.Goods_ser(instance=data, many=True, context={"request": request}).data
return Response({"code": 200, "msg": "ok", "data": data})
else:
return Response({"code": 201, "msg":"缺少参数" }) class Detail(APIView):
def post(self,request):
param=request.data
if param.get("id"):
data = models.Product.objects.filter(disabled=True,product_id=param.get("id")).first()
if data:
data = Goods_ser.Goods_ser(instance=data, many=False, context={"request": request}).data
print(data)
return Response({"code": 200, "msg": "ok", "data": data})
else:
return Response({"code": 201, "msg": "没有该商品"})
Goods
import importlib from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.cache import cache
from app01 import models
from app01.comment import func
import hashlib, time
from django.db import transaction from django import forms class OrderForm(forms.Form):
phone = forms.CharField(
error_messages={
"required": "手机号不能为空"
},
# 调用Form组件中的验证器来校验手机号
# validators=[RegexValidator(r'1[1-9][0-9]{9}', '手机号格式不正确')],
)
token = forms.CharField(error_messages={
"required": "token不能为空"
})
province = forms.CharField(error_messages={
"required": "省份不能为空"
})
city = forms.CharField(error_messages={
"required": "城市不能为空"
})
county = forms.CharField(error_messages={
"required": "县/区不能为空"
})
address = forms.CharField(error_messages={
"required": "详细地址不能为空"
})
name = forms.CharField(error_messages={
"required": "姓名不能为空"
}) class Creat(APIView):
@transaction.atomic
def post(self, request):
param = request.data
form_obj = OrderForm(param)
if form_obj.is_valid() and param['buy_list']:
if request.META.get("HTTP_X_FORWARDED_FOR"):
host_ip = request.META["HTTP_X_FROWARDED_FOR"]
else:
host_ip = request.META["REMOTE_ADDR"]
user_cache = cache.get(param['token'])
if user_cache:
openid = user_cache.split("&")[0]
user_data = models.Wxuser.objects.filter(openid=openid).first()
order_data = {"consignee_mobile": param['phone'],
'consignee_name': param['name'],
'wxuser_id': user_data.id,
"memo": param['remark'],
"consignee_area": f"{param['province']},{param['city']},{param['county']}",
"consignee_address": param['address'],
}
buy_list = param['buy_list']
goods_key = list(buy_list.keys())
all_product = models.Product.objects.filter(product_id__in=goods_key)
order_data['order_id'] = func.get_order_id()
order_data['order_total'] = 0
order_data['quantity'] = 0
sid = transaction.savepoint()
for product in all_product:
product.product_id = str(product.product_id)
order_data['order_total'] += product.price * buy_list[product.product_id]
order_data['quantity'] += buy_list[product.product_id]
# 创建子订单
for i in range(3):
stock = product.stock.quantity
new_stock = stock - buy_list[product.product_id]
if new_stock < 0:
transaction.rollback(sid)
return Response({"code": 203, "msg": f"{product.name}库存不足"})
res = models.Stock.objects.filter(quantity=stock, stock_id=product.stock.stock_id).update(
quantity=new_stock)
if not res:
if i == 2:
transaction.rollback(sid)
return Response({"code": 203, "msg": f"创建订单失败"})
else:
continue
else:
break
new_buy_count = product.buy_count + buy_list[product.product_id]
models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count)
order_item_data = {'order_id': order_data['order_id'], 'product_id': product.product_id, \
"name": product.name, "image": product.image, "price": product.price, \
"nums": buy_list[product.product_id], "brief": product.brief}
models.Order_items.objects.create(**order_item_data) # models.Order_items.objects.create(**order_item_data)
models.Order.objects.create(**order_data)
pay_methon = "Wxpay"
try:
pay_file = importlib.import_module(f"app01.Pay.{pay_methon}")
pay_class = getattr(pay_file,pay_methon)
order_data['open_id'] = openid
order_data['ip'] = host_ip
data = pay_class().pay(order_data)
except:
transaction.savepoint_rollback(sid)
return Response({"code": 202, "msg": "未知的支付方式"})
transaction.savepoint_commit(sid)
func.add_task(order_data['order_id'])
return Response({"code": 200, "msg":"ok","data":data})
else:
return Response({"code": 202, "msg": "token已过期"})
else:
return Response({"code": 201, "msg": "缺少参数"}) class Notity(APIView):
def post(self,request,paymethon):
pay_file = importlib.import_module(f"app01.Pay.{paymethon}")
pay_class = getattr(pay_file, paymethon)
data=pay_class().notity(request.data)
if data['status']=="success":
models.Order.objects.filter(order_id=data['order']).updata(pay_status=1)
Order
from rest_framework.views import APIView
from rest_framework.response import Response
from django.core.cache import cache
from app01 import models
import hashlib,time
from app01.wx import wx_Login
class Login(APIView):
def post(self,request):
param=request.data
if param.get("code"):
data=wx_Login.login(param.get("code"))
if data:
val=data['openid']+"&"+data["session_key"]
key=str(int(time.time()))+data['openid']
md5=hashlib.md5()
md5.update(key.encode("utf-8"))
key=md5.hexdigest()
cache.set(key,val)
has_user=models.Wxuser.objects.filter(openid=data['openid']).first()
if not has_user:
models.Wxuser.objects.create(openid=data['openid'])
return Response({"code":200,"msg":"ok",'data':{"login_key":key}}) else:
return Response({"code":200,"msg":"code错误"})
else:
return Response({"code": 200, "msg": "缺少参数"})
User
wx
import xadmin
from xadmin import views
from app01 import models class BaseSetting(object):
"""xadmin的基本配置"""
enable_themes = True # 开启主题切换功能
use_bootswatch = True xadmin.site.register(views.BaseAdminView, BaseSetting) class GlobalSettings(object):
"""xadmin的全局配置"""
site_title = "商城后台" # 设置站点标题
site_footer = "饼哥有限公司" # 设置站点的页脚
menu_style = "accordion" # 设置菜单折叠 xadmin.site.register(views.CommAdminView, GlobalSettings) xadmin.site.register(models.Order_items)
xadmin.site.register(models.Product)
xadmin.site.register(models.Order)
xadmin.site.register(models.Category)
xadmin.site.register(models.Stock)
xadmin.site.register(models.Images)
xadmin.site.register(models.Wxuser) xadmin.site.register(models.Banner)
adminx
from django.db import models # Create your models here.
'''
#banner
id
image_url
product_id
is_show
w_order
create_time
update_time #销量最高的排前面,销量一样,权重大的在前面
#product_id
id
name
price
intor
buy_count
w_order (越大越前)
detail
image_url
scort #库存
is_show
catory_id
create_time
update_time #scort库存
id
name
num
create_time
update_time #category_id
id
cate_name
image_url
parent_id
create_time
update_time #imgae
id
imgae_url
name
create_time
update_time #订单
order_id
商品总数量
总价格
收货地址
用户id
订单状态(是否取消)
收货人电话
收人姓名
支付
create_time
update_time order_item
id
order_id
商品id
商品价格
num
image_url
create_time
update_time ''' # Create your models here.
class Wxuser(models.Model):
id = models.AutoField(primary_key=True)
openid=models.CharField(max_length=255)
name = models.CharField(max_length=50)
avatar = models.CharField(max_length=200)
language = models.CharField(max_length=50)
province = models.CharField(max_length=50)
city = models.CharField(max_length=50)
country = models.CharField(max_length=50)
gender = models.CharField(max_length=50),
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.openid class Category(models.Model):
cat_id=models.AutoField(primary_key=True)
category_name=models.CharField(max_length=50)
parent=models.ForeignKey(to='Category', to_field='cat_id', related_name="Category", on_delete=models.CASCADE, db_constraint=False,blank=True,null=True)
p_order=models.IntegerField(default=0)
is_show =models.BooleanField(default=1)
image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False,null=True)
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.category_name class Images(models.Model):
image_id=models.AutoField(primary_key=True)
name=models.CharField(max_length=30,default="")
image_url=models.ImageField(upload_to="")
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name class Product(models.Model):
product_id=models.AutoField(primary_key=True)
name=models.CharField(max_length=200)
price=models.DecimalField(max_digits=10, decimal_places=2)
weight=models.IntegerField(default=0)
cat = models.ForeignKey(to="Category", to_field="cat_id", related_name="Product", db_constraint=False, on_delete=models.CASCADE)
intor = models.TextField(max_length=250)#详细介绍
brief = models.TextField(max_length=250)#商品简介
image=models.OneToOneField(to='Images',to_field='image_id',on_delete=models.CASCADE,db_constraint=False)
stock = models.OneToOneField(to="Stock", to_field="stock_id", db_constraint=False, on_delete=models.CASCADE)
buy_count=models.IntegerField(default=0)#购买量
disabled = models.BooleanField(default=1)#是否显示
w_order=models.IntegerField(default=0)#权重
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name class Order(models.Model):
order_id = models.CharField(max_length=50, unique=True, primary_key=True)
status_choices = (("active", '活动订单'), ("dead", '作废订单'), ("finish", '已完成订单'))
status = models.CharField(choices=status_choices, default="active", max_length=50)
pay_status_choices = ((0, '未付款'), (1, '已付款'))
pay_status = models.SmallIntegerField(choices=pay_status_choices, default=0)
payed = models.DecimalField(max_digits=10, decimal_places=2,default=0)
order_total = models.DecimalField(max_digits=10, decimal_places=2,default=0)
ship_status_choices = ((0, '未发货'), (1, '已发货'))
pay_app = models.CharField(max_length=100)
wxuser = models.ForeignKey(to="Wxuser", to_field="id", related_name="Order", db_constraint=False,on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
memo = models.CharField(max_length=200, default=0)
consignee_name = models.CharField(max_length=200, default=0)
consignee_area = models.CharField(max_length=200, default=0)
consignee_address = models.CharField(max_length=200, default=0)
consignee_zip = models.CharField(max_length=200, default=0)
consignee_mobile = models.CharField(max_length=200,default=0)
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.order_id class Order_items(models.Model):
item_id = models.AutoField(primary_key=True)
order= models.ForeignKey(to="Order", to_field="order_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE)
product=models.ForeignKey(to="Product", to_field="product_id", related_name="Order_items", db_constraint=False,on_delete=models.CASCADE,null=True)
name = models.CharField(max_length=200)
image = models.ForeignKey(to='Images', to_field='image_id',related_name="Order_items", on_delete=models.CASCADE,db_constraint=False)
price = models.DecimalField(max_digits=10, decimal_places=2,default=0)
amount=models.DecimalField(max_digits=10, decimal_places=2,default=0)
nums=models.IntegerField()
send_nums=models.IntegerField(null=True)
brief=models.CharField(max_length=200)
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True) class Stock(models.Model):
stock_id=models.AutoField(primary_key=True)
name=models.CharField(max_length=100)
quantity=models.IntegerField(default=0)#库存量
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name class Banner(models.Model):
product = models.OneToOneField(to="Product", to_field="product_id", db_constraint=False, on_delete=models.CASCADE)
w_order = models.IntegerField(default=0) # 权重
image = models.OneToOneField(to='Images', to_field='image_id', on_delete=models.CASCADE, db_constraint=False)
is_show =models.BooleanField(default=1)
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.product.name
models
pro_celery
import celery
import time
# broker='redis://127.0.0.1:6379/2' 不加密码
backend='redis://127.0.0.1:6379/1'
broker='redis://127.0.0.1:6379/2'
cel=celery.Celery('test',backend=backend,broker=broker) import os, sys
import django
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # 定位到你的django根目录
# sys.path.append(os.path.join(BASE_DIR, "app01"))
sys.path.append(os.path.abspath(BASE_DIR))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wxshop.settings")
django.setup()
from django.db import transaction @cel.task
@transaction.atomic
def del_order(order_id):
'''
1 拿订单查询,订单号,是否支付,活跃
2 判断data是否有 :param order_id:
:return:
'''
from app01 import models
data=models.Order.objects.filter(order_id=order_id,pay_status=0,status="active").first()
if data:
item_data=models.Order_items.objects.filter(order_id=order_id).values("product","nums")
# [{product:1,nums:3}]
# {1:3,2:1}
all_product_dict = { k['product']:k['nums'] for k in item_data}
all_product_id =list(all_product_dict.keys())
products_all=models.Product.objects.filter(product_id__in=all_product_id)
sid=transaction.savepoint() for product in products_all:
for i in range(3):
stock=product.stock.quantity
new_stock=stock+all_product_dict[product.product_id]
new_buy_count=product.buy_count-all_product_dict[product.product_id]
res=models.Stock.objects.filter(quantity=stock,stock_id=product.stock).update(quantity=new_stock)
if not res:
if i==2:
from app01.comment import func
transaction.savepoint_rollback(sid)
func.add_task(order_id,1)
return
else:
continue
else:
break
models.Product.objects.filter(product_id=product.product_id).update(buy_count=new_buy_count) row=models.Order.objects.filter(order_id=order_id,pay_status=0).update(status="dead")
if row:
transaction.savepoint_commit(sid)
else:
transaction.savepoint_rollback(sid)
celery
wxshopapi2
"""
Django settings for wxshopapi2 project. Generated by 'django-admin startproject' using Django 2.0.7. For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '$v^um*l969ywfw2$3=rv5y&ehv$b@e#w&ha(%t!_+rv3=3#74n' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'rest_framework',
'xadmin',
'crispy_forms',
'reversion',
] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ROOT_URLCONF = 'wxshopapi2.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'wxshopapi2.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'wxshop',
'USER':'root',
'PASSWORD':'',
'HOST':'127.0.0.1',
'PORT': 3306,
'OPTIONS': {'charset': 'utf8mb4'},
}
} # Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static'),
]
MEDIA_ROOT=os.path.join(BASE_DIR,'static/media') MEDIA_URL = '/static/media/'
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
},
}
settings
"""wxshop URL Configuration The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
import xadmin
xadmin.autodiscover() # version模块自动注册需要版本控制的 Model
from xadmin.plugins import xversion
xversion.register_models()
from django.conf.urls import url
from app01.views import User,Banner,Goods,Category,Order
urlpatterns = [
path(r'xadmin/', xadmin.site.urls),
path('admin/', admin.site.urls),
path("user/wxapp/login",User.Login.as_view()),
path("banner/list",Banner.List.as_view()),
path("hotgoods/list",Goods.HotGoods.as_view()),
path("category/all",Category.All.as_view()),
path("goods/list",Goods.List.as_view()),
path("goods/detail",Goods.Detail.as_view()),
path("order/create",Order.Creat.as_view()),
]
urls
day88_11_8,事务的隔离级别celery定时订单与项目整合。的更多相关文章
- SQL Server 之 事务与隔离级别实例讲解
SQL Server 之 事务与隔离级别实例讲解 SQL Server 实现了6个隔离级别来防止并发情况下,类似企图并发的访问或修改同一数据时问题的发生.本文将带你体验全部6个隔离级别.正如你接下来将 ...
- SQLServer 事务的隔离级别
SQLServer事务的隔离级别 数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务 ...
- Hibernate中事务的隔离级别设置
Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下
- MySQL事务学习-->隔离级别
MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...
- SQL Server事务的隔离级别
SQL Server事务的隔离级别 ########## 数据库中数据的一致性 ########## 针对并发事务出现的数据不一致性,提出了4个级别的解决方法: 隔离级别 第一类丢失更新 脏读 ...
- 事务的隔离级别及mysql对应操作
/* 本次高并发解决之道 1,更改事务隔离级别为 read uncommitted读未提交 2,查询前设定延迟,延迟时间为随机 50-500 微秒 3,修改数据前将 超范围作为 限定修改条件 事务是作 ...
- MySQL(26):事务的隔离级别出现问题之 幻读
1. 幻读 幻读(Phantom Read)又称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不重复读有些类型,同样是在两次查询过程中,不同的是,幻读是由于其他事务做了插入记录的操作,导致记 ...
- MySQL(25):事务的隔离级别出现问题之 不可重复读
1. 不可重复读 所谓的不可重复读(Non-Repeatable Read)是指事务中两次查询的结果不一致,原因是在查询的过程中其他事务做了更新的操作. 例如,银行在做统计报表的时候,第一次查询a账户 ...
- MySQL(24):事务的隔离级别
1. 事务的隔离级别引入: 数据库是多线程并发访问的,所以很容易出现多个线程同时开启事务的情况,这样的就会出现脏读.重复读以及幻读的情况.在数据库操作中,为了有效保证并发读取数据的正确性,需要为事务设 ...
随机推荐
- python3 print() 函数带颜色输出 示例
1.1 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以ESC开头,即用\033来完成(ESC的ASCII码用十进制表示是27,用八进制表示就 ...
- HTML+CSS基础知识点简要汇总(思维导图)
- 一文解读Redis (转)
本文由葡萄城技术团队编撰并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 引言 在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原 ...
- 《收获,不止SQL优化》这本书,有很多即用的脚本工具,或者根据自己的需求,改造重用,可以积累到自己的工具库中。
以下两个脚本,官方来源: https://github.com/liangjingbin99/shouhuo/tree/master/%E7%AC%AC05%E7%AB%A0 1. 找出未使用绑定变量 ...
- C语言复习上
通常开始学习C语言的时候,第一句写的就是"helloword" int main(){ printf("hello word"); } 接下来的日子里需要注意的 ...
- mysql学习体系
1. MySQL的安装和配置 -- 安装的步骤 -- 配置参数的设置 -- 全局变量量与会话变量量的定义及区别 -- 常⻅见参数有哪些,有何定义,影响范围是什什么 -- 如何查看参数的值 -- 配置⽂ ...
- element form 对单个字段做验证
this.$refs[formName].validateField('phone', phoneError => { //验证手机号码是否正确 if (!phoneError) { conso ...
- PHP—— 商品物流实时查询接口 (快递100API对接)
PHP后台 与前端 对接商品物流信息的接口 运用的 快递100的API接口 public function getExpress() { $user_id = input('post.user_ ...
- nginx如何实现负载均衡以及实现方式
什么是ngnix? Nginx是一个http服务器.是一个使用c语言开发的高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.nginx能够支撑5万并发链接,并且cpu ...
- 秒懂:tomcat的maxConnections、maxThreads、acceptCount 图解
后面附图 | 秒懂 疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 前言 疯狂创客圈(笔者尼恩创建的高并发研习社群)Springcloud 高并发系列文章,将为大家介 ...