一。事务的隔离级别。

  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定时订单与项目整合。的更多相关文章

  1. SQL Server 之 事务与隔离级别实例讲解

    SQL Server 之 事务与隔离级别实例讲解 SQL Server 实现了6个隔离级别来防止并发情况下,类似企图并发的访问或修改同一数据时问题的发生.本文将带你体验全部6个隔离级别.正如你接下来将 ...

  2. SQLServer 事务的隔离级别

    SQLServer事务的隔离级别 数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务 ...

  3. Hibernate中事务的隔离级别设置

    Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下

  4. MySQL事务学习-->隔离级别

    MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...

  5. SQL Server事务的隔离级别

    SQL Server事务的隔离级别 ########## 数据库中数据的一致性 ########## 针对并发事务出现的数据不一致性,提出了4个级别的解决方法:  隔离级别  第一类丢失更新  脏读 ...

  6. 事务的隔离级别及mysql对应操作

    /* 本次高并发解决之道 1,更改事务隔离级别为 read uncommitted读未提交 2,查询前设定延迟,延迟时间为随机 50-500 微秒 3,修改数据前将 超范围作为 限定修改条件 事务是作 ...

  7. MySQL(26):事务的隔离级别出现问题之 幻读

    1. 幻读 幻读(Phantom Read)又称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不重复读有些类型,同样是在两次查询过程中,不同的是,幻读是由于其他事务做了插入记录的操作,导致记 ...

  8. MySQL(25):事务的隔离级别出现问题之 不可重复读

    1. 不可重复读 所谓的不可重复读(Non-Repeatable Read)是指事务中两次查询的结果不一致,原因是在查询的过程中其他事务做了更新的操作. 例如,银行在做统计报表的时候,第一次查询a账户 ...

  9. MySQL(24):事务的隔离级别

    1. 事务的隔离级别引入: 数据库是多线程并发访问的,所以很容易出现多个线程同时开启事务的情况,这样的就会出现脏读.重复读以及幻读的情况.在数据库操作中,为了有效保证并发读取数据的正确性,需要为事务设 ...

随机推荐

  1. 一起学SpringMVC之Request方式

    本文主要以一些简单的小例子,简述在SpringMVC开发过程中,经常用到的Request方面的内容,仅供学习分享使用,如有不足之处,还请指正. 概述 在客户机和服务器之间进行请求-响应时,两种最常被用 ...

  2. Flask 模板语言,装饰器

      Jinja2模板语言 # -*- coding: utf-8 -*-   from flask import Flask, render_template, request, redirect,  ...

  3. Apply Grouping to List View Data 将分组应用于列表视图数据

    This lesson will teach you how to apply grouping to List View data. For this purpose, you will group ...

  4. MySQL创建、修改、删除数据库

    创建数据库 CREATE DATABASE [IF NOT EXISTS] t1 CHARACTER SET [=] utf8: 中括号中的代码可有可无:CHARATER如果不写则创建为默认的字符. ...

  5. 急速下载pandas

    使用国内源进行下载: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua ...

  6. 一文带你深入浅出Spring 事务原理

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  7. VS2010到VS2019各个版本的密钥

    VS2019专业版和企业版的密钥 Visual Studio 2019 EnterpriseBF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Profe ...

  8. (五十六)c#Winform自定义控件-瓶子(工业)-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  9. 一起学Android之Animation

    本文以一个简单的小例子,简述在Android开发中,动画的简单应用,仅供学习分享使用. 概述 android提供了各种强大的apis,用于将动画应用到ui元素中,来丰富应用程序的功能和应用. 动画分类 ...

  10. ASP.NET Core 2.2 WebApi 系列【二】使用EF CodeFirst创建数据库

    Code First模式 Code First是指"代码优先"或"代码先行". Code First模式将会基于编写的类和配置,自动创建模型和数据库. 一.准备 ...