一 事务与锁

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. Nodejs的介绍

    Nodejs的介绍 Node.js的是建立在Chrome的JavaScript的运行时,可方便地构建快速,可扩展的网络应用程序的平台.Node.js使用事件驱动,非阻塞I/O模型,轻量.高效,可以完美 ...

  2. 老男孩教育每日一题-2017年3月29日-使用ifconfig取出网卡eth0的ip地址-看看你有多少方法...

    方法1:sed命令 [root@oldboyedu ~]# ifconfig eth0 |sed -n '2p' |sed's#^.*addr:##g'|sed 's#  B.*$##g' 10.0. ...

  3. CodeForces - 1245A Good ol' Numbers Coloring (思维)

    Codeforces Round #597 (Div. 2 Consider the set of all nonnegative integers: 0,1,2,-. Given two integ ...

  4. postman(动态数据获取)

    一:返回报文为 json 格式 示例:因为充值记录接口中需要用到登录接口返回报文中的信息如下 1.以获取token(JWT)和uid为例 2.在登录接口的tests中写入代码(因为登录接口报文信息中有 ...

  5. 聊聊select, poll 和 epoll_wait

    聊聊select, poll 和 epoll 假设项目上需要实现一个TCP的客户端和服务器从而进行跨机器的数据收发,我们很可能翻阅一些资料,然后写出如下的代码. 服务端 客户端 那么问题来了,如果有一 ...

  6. redis 6.0下redis-cluster-proxy代理尝试

    伴随着Redis6.0的发布,作为最令人怦然心动的特性之一,Redis官方同时推出Redis集群的proxy了:redis-cluster-proxy,https://github.com/Redis ...

  7. Python解决钻石小偷问题

    题目如下: A:我没有偷钻石. B:D就是罪犯. C:B是盗窃这块钻石的罪犯. D:B有意诬陷我. 假定只有一个人说的是真话,编程序判断谁偷走了钻石. 答案是:说真话的是D,罪犯是A,逻辑思路可以百度 ...

  8. go 模板详说

    模板是我们常用的手段用于动态生成页面,或者用于代码生成器的编写等.比如把数据库的表映射成go语言的struct,这些体力活,写个代码生成器是最合适不过的了. 示例例把表转成 struct : 当然这篇 ...

  9. H. Subsequences (hard version) dp

    H. Subsequences (hard version) 这个题目好难啊,根本就不知道怎么dp,看了题解,理解了好一会才会的. 首先dp[i][j] 表示前面 i  个字符,形成长度为 j  的不 ...

  10. 设计模式(Java语言)- 建造者模式

    前言 在日常的生活中,我们可以经常看到建造者模式的影子.比如,建造房子,那么房子就是一个产品,房子由门,窗,墙,地板等部门组成.然后包工头在建造房子的时候就根据设计好的图纸来建造,但是包工头并不是亲自 ...