版权归作者所有,任何形式转载请联系作者。
作者:petanne(来自豆瓣)
来源:https://www.douban.com/note/580618150/

缘由:有一个django守护进程Daemon一直在后台运行,轮询读数据库,导致被锁无法ALTER表结构。
涉及django==1.4 django==1.9 mysql

在1.4中(1.5之前版本均为这样),默认的transaction为autocommit,在读写数据库时,均会对数据表产生一个状态为RUNNING的事务,写操作在save的时候会触发autocommit,结束该事务,但是读操作不会触发autocommit,导致该事务一直RUNNING,并且不能对表结构进行操作。

注:1.6之前的autocommit只对写操作有效,对读操作无效!
注:1.6之前的autocommit只对写操作有效,对读操作无效!
注:1.6之前的autocommit只对写操作有效,对读操作无效!

先看看这个很有趣的例子,复现方式:
1.在django的python shell 环境下执行一条读语句
python manage.py shell
>>User.objects.get(id=1)
<User: xxxxx>

2.在mysql shell里执行
>>use information_schema;
>>select * from INNODB_TRX \G;
此时,可以看到有一个RUNNING的事务
>>show processlist;
此时,可以看到process里有一个Id字段为上面事务的trx_mysql_thread_id的process,然后看该process的Host字段(通信的客户端IP和端口),可以确定此事务即为1步骤读操作占用。

3.退出1中的python shell,可发现2中RUNNING的事务被结束。

也就是说,守护进程Daemon一直运行不退出的话,只要里面有读操作,就会因为事务占用一直锁住这个表。同理,每次web请求,使用ORM读的时候,也是这样,但web请求结束django关掉数据库连接,就会结束该事务。

解决方法:
在django==1.5版本之前,在Daemon里每次执行完读操作后,都手动commit一下
方法1:
>>from django.db import transaction
>>User.objects.get(id=1)
>>transaction.commit()
方法2:将查询语句置于事务管理commit_on_success的block下,顾名思义,其作用为在block中的代码执行完毕且无Exception的时候自动commit
>>with transaction.commit_on_success():
        User.objects.get(id=1)

django==1.6版本,在settings.py的数据库配置项DATABASES中,添加了"AUTOCOMMIT"参数,默认为True,详见文档https://docs.djangoproject.com/en/dev/ref/settings/#autocommit,即为所有操作自动提交。
另外注意在1.6 至 1.6.2版本中,该参数有BUG,会导致AUTOCOMMIT不生效,django在1.6.2版本fix了该BUG,详见https://docs.djangoproject.com/en/1.10/releases/1.6.2/

django autocommit的一个坑,读操作的事务占用导致锁表的更多相关文章

  1. Hiver 操作 MySQL 导致锁表

    Hadoop 搬迁到新集群后,操作主库 MySQL 导致了锁表...sad 具体锁表时间点  : 2016-1-14 14:31  到   2016-1-14 14:36 之间 在 oradba 的 ...

  2. mysql批量update操作时出现锁表

    https://www.cnblogs.com/wodebudong/articles/7976474.html 最近遇到一件锁表的情况,发现更新的语句where检索的字段,没有建索引,且是批量操作的 ...

  3. LSM树——LSM 将B+树等结构昂贵的随机IO变的更快,而代价就是读操作要处理大量的索引文件(sstable)而不是一个,另外还是一些IO被合并操作消耗。

    Basic Compaction 为了保持LSM的读操作相对较快,维护并减少sstable文件的个数是很重要的,所以让我们更深入的看一下合并操作.这个过程有一点儿像一般垃圾回收算法. 当一定数量的ss ...

  4. django中static的坑

    在django搭建网络平台的时候免不了要使用到static来保存静态文件, 在static文件夹里包含两个文件:css和js文件,如果使用不当就会出现很多问题 第一个坑:配置文件settings.py ...

  5. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  6. NoSql数据库初探-mongoDB读操作

    MongoDB以文档的形式来存储数据,此结果类似于JSON键值对.文档类似于编程语言中将键和值关联起来的结构(比如:字典.Map.哈希表.关联数组).MongoDB文档是以BOSN文档的形式存在的.B ...

  7. 困扰多日的C#调用Haskell问题竟然是Windows的一个坑

    最近一直被C#调用Haskell时的“尝试读取或写入受保护的内存”问题所困扰(详见C#调用haskell遭遇Attempted to read or write protected memory,C# ...

  8. CI中获取读操作的结果集行数+获取写操作的影响行数

    本质:读操作,用mysql_num_rows函数,写操作用mysql_affected_rows函数 mysql_num_rows() 返回结果集中行的数目.此命令仅对 SELECT 语句有效.要取得 ...

  9. 怎么看时序图--nand flash的读操作详解(转载)

    出处:http://blog.chinaunix.net/uid-28852942-id-3992727.html这篇文章不是介绍 nand flash的物理结构和关于nand flash的一些基本知 ...

随机推荐

  1. C#彻底解决Oledb连接Excel数据类型不统一的问题

    在使用Microsoft.Jet.OLEDB.4.0连接Excel,进行读取数据,相对使用传统的COM来读取数据,效率是很高的.但相对传统COM操作Excel来说,及存在数据类型转换的问题.因为使用O ...

  2. 九度OJ 1187:最小年龄的3个职工 (排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2291 解决:936 题目描述: 职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来. 输入: 输入第一行包括1个 ...

  3. Lock和Condition

    1 什么是可重入锁 可重入锁是说一个线程在已经获取了该锁的情况下,还可以再次获取该锁. 主要的应用场景: 可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又 ...

  4. 【python】-- SQLAlchemy操作MySQL

    ORM.SQLAchemy orm英文全称object relational mapping,就是对象映射关系程序,简单来说就是类似python这种面向对象的程序来说一切皆对象,但是使用的数据库却都是 ...

  5. [APIO2008]免费道路

    [APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...

  6. table control里面各种属性和事件

    [转自]http://blog.csdn.net/hackai886/article/details/7935366 SAP中,Table Control是在Screen中用的最广泛的控件之一了,可以 ...

  7. 【转载】Spring介绍之二

    Spring框架,是进行对象管理,对象关联,解耦的一个中间层框架.SSH(Struts+Spring+Hibernate)三大Spring在中间就起着一个承上启下的作用.好,首先我们先来看一下Spri ...

  8. python cookbook 字符串和文本

    使用多个界定符分隔字符串 import re line = 'asdf fjdk; afed, fjek,asdf, foo' print(re.split(r'[;,\s]\s*', line)) ...

  9. python cookbook 数据结构

    保留最后n个元素: from collections import deque def search (lines, pattern, history=): previous_lines = dequ ...

  10. 【leetcode刷题笔记】Jump Game II

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...