一 事务与锁

1.行级锁

行级锁是由存储引擎实现的。如mysql里默认指定的InnoDB存储引擎,由它实现行级锁。InnoDB的行级锁定同样分为两种类型,共享锁(X)和排他锁(S)。

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁

事务可以通过以下语句显示给记录集加共享锁或排他锁。

共享锁(S):SELECT * FROM table_name WHERE .. LOCK IN SHARE MODE

排他锁(X):SELECT * FROM table_name WHERE .. FOR UPDATE

修改时,加了排他锁,其他临时会话不能查和修改等操作

Lock table tab_name write;给表加了写锁,临时会话不能往里面写。

Unlock tables;    解除写锁

2.ORM里加锁

加行级锁:select_for_update(nowait=False, skip_locked=False)

加行级锁必须用在事务里。

手动加互斥锁:

entries = models.Entry.objects.select_for_update().filter(author=request.user)

共享锁Mysql会自动加,因此不需用加共享锁。create、update、delete操作时,mysql自动加行级互斥锁,因此查看时可加互斥锁。

所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。

3.事务

(1)事务简介

事务具有ACID属性

事务控制语句

BEGIN或START TRANSACTION;显式地开启一个事务;

COMMIT;               COMMIT会提交事务,并使已对数据库进行的所有修改成为永久性的;

ROLLBACK;            回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

SAVEPOINT identifier;    SAVEPOINT允许在事务中创建一个保存点,一个事务中可以有多个SAVEPOINT;

RELEASE SAVEPOINT identifier;    删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

ROLLBACK TO identifier;   把事务回滚到标记点;

(2)Django里事务操作

Django里开启事务有两大类,一是全局形式,二是局部形式。

a.全局形式

方法:在用户settings.py文件里,在DATABASES配置里,加入 "ATOMIC_REQUESTS":True。

原理:当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求正确处理并正确返回了结果,Django就会提交该事务。否则,Django会回滚该事务。因此全局开启事务,绑定的是http请求响应整个过程。

b.局部形式

atomic(using=None, savepoint=True)[source]

atomic是原子性。使用atomic,我们就可以创建一个具备原子性的代码块。一旦代码块正常运行完毕,所有的修改会被提交到数据库。反之,如果有异常,更改会被回滚。(要么全成功,要么全失败)

(i)方式一:装饰器

from django.db import transaction
@transaction.atomic
def viewfunc(request):
   do_stuff() 里面代码就在事务里

(ii)方式二:上下文管理器(设置事务的保存点)

from django.db import transaction
def viewfunc(request):
do_stuff() #这段代码使用默认的方式
with transaction.atomic(): #保存点
do_more_stuff() #这段代码在事务里
  do_other_stuff()

注意::如果配置了全局的事务,它和局部事务可能会产生冲突。比如说:局部的事务完成之后,如果该函数里面其他的sql出了问题,那么局部事务也是提交不上。因为全局会回滚这个请求和响应所涉及到的所有的sql(局部的也被回滚了)。建议项目用局部事务。

设置事务小原则:

1.保持事务短小

2.尽量避免事务中rollback

3.尽量避免savepoint

4.默认情况下,依赖于悲观锁

5.为吞吐量要求苛刻的事务考虑乐观锁

6.显示声明打开事务

.锁的行越少越好,锁的时间越短越好

Ajax使用

一、Ajax介绍

Ajax:Asynchronous Javascript And XML。即异步的Javascript和XML。使用Javascript语言与服务器进行异步交互,传输的数据为XML(现在多为json)

(一)Ajax两大特性:

异步交互和局部刷新。

异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。同步交互指客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求。

局部刷新:不会刷新整个页面,局部内容发生变化。

(二)应用场景

1.搜索引擎根据用户输入的关键字,自动提示检索关键字。

2.注册时候的用户名的查重。(提示该用户已经注册过了)

当输入用户名后,光标移动到其他表单项时,浏览器会使用AJAX技术向服务器发出请求(这个时候你可以继续其他操作,这就是异步交互),服务器会查询用户名是否存在,然后返回结果(这个页面没有刷新,只有局部内容刷新了)。

二、Ajax操作

做个简单的注册页面,利用Ajax实现异步请求和局部刷新

(一)django基本设置

静态文件配置(引入juqery.js),分发路由操作

(二)操作

1.回复html页面

2.写html文件

ajax上传文件:<input type="file" id="file">

ajax用户名:<input type="text" id="uname">

<button id="btn">提交</button>

注意:form表单最后的提交按钮的type必须时button。如果还是写submit,那么提交还是按照form表单提交,不按照ajax提交。提交方式与form表单无关了,自然服务器取数据也与input标签的name值无关了。

3.ajax代码接收用户数据

(1)绑定事件

$('#btn').click(function () {}

给提交按钮绑定点击事件。

(2)ajax

通过 $.ajax({})方式来使用ajax。{}里是字典,主要包括三大部分url、type和success。浏览器有数据时还需data获取数据。

data内容:

data:{
uname:$('#username').val(), {# 获取数据 #}
pwd:$('#password').val(),
//csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(), {#和form表单一样的crsf #}
//方式二:
csrfmiddlewaretoken: '{{ csrf_token }}'
},

data数据是字典的形式。键为后台获取值的关键字。值:先定位到html文件里数据的标签,再通过val()取值。data数据里还要给后台传输csrf值(post请求提交要验证):html标签里有,直接以键值对的形式传输过去。

4.后台处理数据并发送数据给ajax

Ajax将data数据发给后台,后台在视图函数进行处理:

(1)获取ajax发来的数据

name=request.POST.get('uname')

pwd=request.POST.get('pwd')

(2)匹配成功---进行数据处理和给ajax发消息

根据取来的值和数据库的进行比较,如果再数据库里,就给用户返回首页。不用ajax的话,django就直接重定向redirect。但用ajax,ajax识别不了redirect。因此要给ajax回复一个字典,让ajax进行重定向。

字典里有code码。方便ajax做判断,再做不同的处理。

发送形式:django发送给浏览器只有两种。Render发网页,HttpResponse发字符串。因此发过去的字典必须是字符串形式的。而ajax那边需要的是字典形式的数据。因此需要用到json解析。

数据传输

方式一:(不推荐)

发送端:字典外面直接包裹‘’,写成字符串的形式(注意json格式。里面都是双引号,最外面单引号),然后通过HttpResponse发送过去

 ret = '{"code":0,"redirect_url":"/index/"}'
return HttpResponse(ret)

接收端:JSON.parse(接收数据)  去掉’’,由字符串变成字典

var resStr=JSON.parse(res);

res是响应数据,从success:function (res)里接收

方式二:

用dumps方法将ret转为json字符串

d1={"code":0,"redirect_url":"/index/"}
import json
d1_json=json.dumps(d1) #给字典外面加个单引号,里面都是双引号 return HttpResponse(d1_json,content_type='application/json') #声明数据是json格式的,ajax接收数据不用反序列化。

HttpResponse发送json字符串过去时,可以再后面告诉ajax这个数据的格式是json格式的,ajax接收数据不用反序列化,可以直接处理。

方式三:

利用Django的JsonResponse方法。

from django.http import JsonResponse
d1 = {"code": 0, "redirect_url": "/index/"}
return JsonResponse(d1)

JsonResponse内部有转化json字符串的功能,同时也声明了类型是json。因此直接传输数据给ajax。Ajax也不需要反序列化。

(3)匹配失败:

匹配失败,也需告诉ajax信息,让ajax操作。

ret = '{"code":3,"redirect_url":"用户名或者密码错误"}'
return HttpResponse(ret)

5.ajax处理后台的数据,并操作dom标签

Ajax接收到后台的数据,并进行处理,这部分代码都写在success:function (res) {}字典里。参数res是后台的响应数据,即传过来的值。

(1)针对不同code做不同的处理

如果是code是3,即用户名或密码错误,就新增标签给用户提示。(标签这个也可以写在html里。)

 success:function (res) {
console.log(res); {#res为响应数据#}
var resStr=JSON.parse(res); {# 反序列化 解析res,由字符串变为字典 直接传过来json字符串需要,用dumps序列化并且发送过来声明类型了或者是JsonResponse发送过来不需要反序列化#}
if (resStr['code']===3){
{#局部刷新:'{"code":3,"redirect_url":"用户名或者密码错误"}'#}
var spanEle=document.createElement('span');
$(spanEle).text(resStr['redirect_url']);
$('form').append(spanEle);
}

(2)如果输入正确,即code=0,就重定向

 location.href=resStr['redirect_url'];

(三)Ajax补充:

1.ajax流程

Ajax代码可以通过外部文件引入的方式导入到html文件。但这有一个问题:加载顺序会导致ajax里的模板渲染失败({{}}和{%%})。

地址栏输入网址------》django进行路由分发------》执行逻辑函数--------》渲染html文件---------》把渲染好的html给浏览器渲染------》浏览器再次渲染。

如果ajax文件是通过外部方式导入的,django在模板渲染时是渲染不到ajax的。浏览器渲染HTML文件时才加载ajex文件,此时django已经渲染结束了。

解决方法:ajax是外部文件时,js语法就不要用django的模板语法。

2.ajax的csrf_token验证

三个方式:(1)通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。(2)模板语法。在ajax设置时发送数据过去。(3)通过获取返回的cookie中的字符串 放置在请求头中发送。

(1)"csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()

(2)$.ajaxSetup({

data: {csrfmiddlewaretoken: '{{ csrf_token }}' },

});

三、Ajax文件上传

(一)ContentType介绍

1.简介

ContentType可在请求头中看到,指的是请求体的编码类型。表示的是数据提交的方式。

ContentType类型有三种:application/x-www-form-urlencoded、 multipart/form-data和 application/json。

2.application/x-www-form-urlencoded

urlencoded是最常见的 POST 提交数据的方式。在<form> 表单,如果不设置 enctype 属性,那么最终就会以 默认格式application/x-www-form-urlencoded 方式提交数据,ajax默认也是这个。

数据形式:以&作为分割,通过等于方式连接键和值

3.multipart/form-data

上传文件

使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data

4.application/json

在Network里可以查看到response headers和requests headers。response headers的contenttype是服务器告诉浏览器数据是什么格式封装的。requests headers的contenttype是浏览器告诉服务器,数据是什么格式。

5.ajax里的contenttype

ajax里面写上这个contenttype类型,表示data的数据类型也要变成这个格式。Data默认是urlencoded格式。服务端接受到数据之后,通过contenttype类型的值来使用不同的方法解析数据。django能解析application/x-www-form-urlencoded 和multipart/form-data,但不能解析application/json类型。

Django里可通过request.body取出原始值,再将byte类型的数据转化为字符串。

(二)ajax文件上传

1.操作

Ajax给服务端上传文件的数据不能直接写在data里了,要借助一个FormData的类生成的对象formdata,把文件添加到这个对象中,在通过data发送给服务端。其次,还要在data下面写两个参数,保证ajax上传文件时不对文件内容做任何处理。

(1)把数据添加到formdata对象里

var formdata=new FormData();
formdata.append('aa',$('#uname').val());
formdata.append('headpic',$('#file')[0].files[0]);
formdata.append('csrfmiddlewaretoken',$('[name=csrfmiddlewaretoken]').val());

找到文件操作: $('#file')[0]将jquery对象变为dom对象,利用dom的files方法拿到文件(是个列表),再取第一个值,即是文件内容。

(2)将formdata放到data里,提交给服务端。并且设置参数

data:formdata,
processData:false, //不处理数据(不让预处理)
contentType:false, //不设置内容类型 这两个在ajax上传文件是固定死的.不对文件做任何操作

(3)视图函数最开始要返回页面

    if request.method=='GET':
return render(request,'upload.html')

(4)取到数据

file_obj=request.FILES.get('headpic')

文件必须通过FILES方法取得,file_obj里就有数据。调用该对象的name属性,获得文件名。

(5)写入数据

方式一:

  with open(path,'wb')as f:
for i in file_obj: #每次读一行(以\r \n \r\n为分隔符)
f.write(i)

方式二:

with open(path, 'wb')as f:
for chunk in file_obj.chunks(): #读数据有个固定大小 默认64KB 最大2.5M .django的全局配置里面可以改chunks大小
f.write(chunk) # 64 * 2 ** 10 在base里

Django中的事务与ajax的更多相关文章

  1. django中使用事务以及接入支付宝支付功能

    之前一直想记录一下在项目中使用到的事务以及支付宝支付功能,自己一直犯懒没有完,趁今天有点兴致,在这记录一下. 商城项目必备的就是支付订单的功能,所以就会涉及到订单的保存以及支付接口的引入.先来看看订单 ...

  2. DJango中开启事务的两种方式

    目录 Django中开启事务的两种方式 第一种 第二种 Django中开启事务的两种方式 第一种 from django.db import transaction with transaction. ...

  3. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

  4. django中的事务管理

    在讲解之前首先来了解一下数据库中的事务. 什么是数据库中的事务? 热心网友回答: ():事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不 ...

  5. Django中关于事务的代码编写

    Django中对于数据库的事务,默认每执行一句数据库操作,便会自动提交. 在Django中可以通过django.db.transaction模块提供的atomic来定义一个事务,atomic提供两种用 ...

  6. Django中的事务(Transaction)管理

    Django默认的事务行为 默认情况下,在Django中事务是自动提交的.当我们运行Django内置的模板修改函数时,例如调用model.save()或model.delete()时,事务将被立即提交 ...

  7. django中通过文件和Ajax来上传文件

    一.通过form表单来上传文件 1.在html模板中 <form action="/index/" method="post" enctype=" ...

  8. 在django中解决跨域AJAX

    由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接收罢了. 浏览器同源 ...

  9. Django中MySQL事务的使用

    Django中事物的使用 from django.db import transaction @transaction.atomic通过transaction的@transaction.atomic装 ...

随机推荐

  1. 什么是最好的在线UML软件工具?

    在线UML软件工具允许您创建UML图表,而UML绘图工具可帮助维护您的建模工件并促进不同图表中元素的可重用性.一些UML建模工具还提供复杂的建模功能,例如模型转换,报告,代码工程等. 如果您正在寻找U ...

  2. 阿里大牛带你深入分析spring事务传播行为

    spring框架封装了很多有用的功能和组件,便于在项目开发中快速高效的调用,其中spring的事务使用非常简单,只需要在用到事务的地方加一行注解即可: 1@Transactional 但越是看起来简单 ...

  3. 求x>0时,y=x^3-6x^2+15的极值

    解: 当x→∞时,y也→∞,所以y没有最大值. y=x3-6x2+15=-4*(x/2)*(x/2)*(6-x)+15 而根据几何平均数小于等于算术平均数的定理,(x/2)*(x/2)*(6-x)在x ...

  4. 数学--数论--HDU 1299 +POJ 2917 Diophantus of Alexandria (因子个数函数+公式推导)

    Diophantus of Alexandria was an egypt mathematician living in Alexandria. He was one of the first ma ...

  5. Find Minimum in Rotated Sorted Array(旋转数组的最小数字)

    题目描述: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., might become ...

  6. spring mvc 实现文件上传

    例:用户注册提交一个头像文件 第一步,创建项目 ,导入jar包 做文件上传除了要导入spring常规的jar包外,还要导入commons-fifileupload和commons-io这两个jar包. ...

  7. 【Hadoop离线基础总结】linux的shell编程

    linux的shell编程 基本了解 概述 Shell是一个用C语言编写的程序,通过shell用户可以访问操作系统内核服务,它类似于DOS下的command和后来的cmd.exe.Shell既是一种命 ...

  8. 解决编码问题:AttributeError: 'str' object has no attribute 'decode'

    1. 问题发现: 出现:读取文件,对其进行解码,出现错误,AttributeError: 'str' object has no attribute 'decode' 解释:属性错误,str对象不包含 ...

  9. 利用 Maven 构造 Spring Cloud 微服务架构 模块使用 spring Boot构建

    采用Maven 聚合工程搭建 Spring Cloud 使用工具: IntelliJ IDEA    版本: 2019.2.2 maven             版本: 3.6.0 JDK      ...

  10. 常见的GAN网络的相关原理及推导

    常见的GAN网络的相关原理及推导 在上一篇中我们给大家介绍了GAN的相关原理和推导,GAN是VAE的后一半,再加上一个鉴别网络.这样而导致了完全不同的训练方式. GAN,生成对抗网络,主要有两部分构成 ...