save?commit
数据库的隐式提交
先看一段SQL,最后一条SQL的输出你认为是什么?
|
1
2
3
4
5
6
7
|
SET AUTOCOMMIT = 1;BEGIN;INSERT INTO t1 VALUES (1);CREATE TABLE t2 (pk int primary key);INSERT INTO t2 VALUES (2);ROLLBACK;SHOW TABLES; |
答案是:t1, t2都存在!
|
1
2
3
4
5
6
7
8
|
mysql> show tables;+----------------+| Tables_in_test |+----------------+| t1 || t2 |+----------------+2 rows in set (0.00 sec) |
更奇怪的是:t1中的1也插入成功了!
|
1
2
3
4
5
6
7
|
mysql> select * from t1;+----+| pk |+----+| 1 |+----+1 row in set (0.00 sec) |
为什么ROLLBACK没有生效呢?答案是:Implict Commit
执行CREATE TABLE语句前,之前的事务被隐式提交。因为AUTOCOMMIT=1,所以提交后也不会自动新创建任何事务,INSERT语句执行后立即提交,ROLLBACK不会作用在任何事务上,所以得到了我们最后看到的结果。
稍微改一下,让AUTOCOMMIT=0,会怎样呢?
|
1
2
3
4
5
6
7
|
SET AUTOCOMMIT = 0;BEGIN;INSERT INTO t1 VALUES (1);CREATE TABLE t2 (pk int primary key);INSERT INTO t2 VALUES (2);ROLLBACK;SHOW TABLES; |
答案是:t1, t2都存在!插入到t1中的1被提交(插入成功)但插入到t2中得2被回滚(没有插入成功)。之所以t1中的1被提交,是因为CREATE TABLE导致ImplictCOMMIT(注意,是COMMIT,不是ROLLBACK哦!),执行INSERT的时候,会自动开启一个新事务(AUTOCOMMIT=0的语义要求的行为)。所以t2中的2被ROLLBACK回滚。
为什么部分操作会导致Implict Commit?为什么这样设计?
为了保证直观上的原子性。假设不做Implict Commit,看看上面的语句会怎样:用户的心理预期是回滚t1的INSERT操作,以及t2的CREATE操作,INSERT操作。如果我们有能力做到这样,那的确是很完美的。但实际上我们很难做到,特别是在分布式系统中更难!因为CREATE TABLE操作背后涉及到了大量的操作,不仅仅包括对核心表的操作,还包括大量内存数据结构的更新(如Schema),以及存储系统的变更(如创建相应的数据块),工程上很难把这些操作做成原子的。
那么,应该如何做呢?比较折中的方式就是跟用户做一个约定:CREATE TABLE操作总默认COMMIT它之前的事务,这就是implict commit。
从MySQL文档看,他们做这一块的时候遇到了很多问题,至少在这里踩过两个坑。并且,随着版本的进化,他们还不断的让更多语句能引发implict commit。(转)
save?commit的更多相关文章
- modelform save
ModelForm表单 save()方法 每一个ModelForm都有一个save()方法,这个方法可以更具绑定的form表单创建并且保存一个数据库对象,ModelForm的子类可以接受一个model ...
- Django:form.save()方法
参考:https://blog.csdn.net/it_yuan/article/details/53580756 背景: 之前的博客是不支持上传文章缩略图的,后来新增了此功能,但是发现修改老的文章时 ...
- Django-ModelFrom中修改save后的字段值
在ModelForm提交中,保持原未修改字段的值,views中部分代码: project = Iredmail.objects.get(id=id) ssh_crt_name = project.ss ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 《Django By Example》第二章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:翻译完第一章后,发现翻译第二章的速 ...
- Django--自定义用户认证
Django自带的用户认证 以前都是用Django自带的用户认证,用户名字段一对一关系对应Django--User表(其实它也是继承了abstractbaseuser). 1 2 3 from dja ...
- 【Django】--ModelForm组件
ModelForm a.class Meta: model,#对应Model的 fields=None,#字段 exclude=None,#排除字段 labels=None,#提示信息 help_te ...
- Python之路【第二十二篇】CMDB项目
浅谈ITIL TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central ...
- 尝试封装适用于权限管理的通用API
谈谈我对权限系统的简单理解 最近一段时间在研究权限系统,在园子里看到个很牛逼的开源的基于DDD-Lite的权限管理系统,并有幸加入了作者的QQ群,呵呵,受到了很大的影响.对于权限管理我有我自己的一些简 ...
随机推荐
- @RequiresPermissionss是否可以填写多种权限标识,只要满足其一就可以访问?
@RequiresPermissionss是否可以填写多种权限标识,只要满足其一就可以访问? 发布于 180天前 作者 qq_b02c4863 144 次浏览 复制 上一个帖子 下一个帖子 ...
- 【CCPC-Wannafly Winter Camp Day4 (Div1) A】夺宝奇兵(水题)
点此看题面 大致题意: 有\(n\)种宝藏,每种各两个.让你依次获得\(1\sim n\)号宝藏,然后依次获得剩余的\(n\sim1\)号宝藏,求最少步数. 简单结论 其实这题有一个十分简单的结论,即 ...
- 跑groud truth的disparity
1.用这个初始化cv::Mat M(375,1242,CV_32FC1,0.0); ,就会报以下的错误: malloc(): memory corruption: 0x000000000165df40 ...
- 【造轮子】开发vue组件库MeowMeowUI
项目示例 github 1. 创建项目 # 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 webpack 模板的新项目 $ vue in ...
- js 实现链表
我们通常会在c++这类语言中学习到链表的概念,但是在js中由于我们可以动态的扩充数组,加之有丰富的原生api.我们通常并不需要实现链表结构.由于突发奇想,我打算用js实现一下: 首先我们要创建链表: ...
- [转]C++ Template
引言 模板(Template)指C++程序设计设计语言中采用类型作为参数的程序设计,支持通用程序设计.C++ 的标准库提供许多有用的函数大多结合了模板的观念,如STL以及IO Stream. 函数模板 ...
- 泉五培训Day5
T1 陪审团 题目 [题目描述] 陪审团制度历来是司法研究中的一个热议话题,由于陪审团的成员组成会对案件最终的结果产生巨大的影响,诉讼双方往往围绕陪审团由哪些人组成这一议题激烈争夺.小 W提出了一个甲 ...
- ABAP Table Control
SAP中,Table Control是在Screen中用的最广泛的控件之一了,可以实现对多行数据的编辑. 简单来说,Table Control是一组屏幕元素在Screen上的重复出现,这就是它与普通 ...
- js、jquery初始化加载顺序
// ready 这个方法只是在页面所有的DOM加载完毕后就会触发 // 方式1 $(function(){ // do something }); // 方式2 $(document).ready( ...
- Cloudera Manager 安装 CDH5
文档说明 本文是针对Linux CentOS6服务器与CDH5.15的安装手册. 关于CDH和ClouderaManager CDH(Cloudera's Distribution, includin ...