004 --Mysql中的锁的问题
死锁
死锁是指两个或多个事务在同一个资源上相互占用, 并请求锁定对方占用的资源, 从而导致恶性循环的现象. 当多个事务试图以不同顺序锁定资源时, 就可能产生死锁.
死锁发生以后, 只有部分或者完全回滚其中一个事务, 才能打破死锁.
MySQL 中的事务
在 MySQL 提供的众多存储引擎中, 只有 InnoDB 和 NDB Cluster 支持事务.
关于自动提交(AUTOCOMMIT)
MySQL 默认采用自动提交(AUTOCOMMIT) 模式. 即如果不显示地开始一个事务, 则每个操作都被当做一个事务执行提交操作.
我们可以通过
SHOW VARIABLES LIKE 'autocommit';
查询当前是否已经开启了字段提交事务, 例如:
mysql> SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)
如果是 ON, 则表示已经开启了, 0 或 OFF 表示禁用.
可以通过 "set autocommit=0;" 来禁用自动提交:
set autocommit=0;
对于非事务型存储引擎, 例如 MyISAM, 修改 AUTOCOMMIT 属性试不会有影响的.
自动提交和非自动提交的区别
下面以一个例子来展示 autocommit 启动和非启动时的区别.
首先建立一个测试用的表:
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT '',
`age` INT(11) DEFAULT '0',
PRIMARY KEY (`id`)
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
接着关闭自动提交功能:
mysql> set autocommit=0;
然后插入一个数据:
mysql> INSERT INTO user (`id`, `name`, `age`) VALUES (1, 'xys', 18);
接着查看数据:
mysql> select * from user;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | xys | 18 |
+----+------+------+
1 row in set (0.00 sec)
数据库中可以查询到这条数据了.
但是我们通过 SHOW BINLOG EVENTS 查看操作日志:
mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.13-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 1 | 154 | |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)
会发现上面的输出中, 并没有插入数据相关的记录, 并且此时如果我们退出 MySQL 的话, 那么我们插入的数据并没有被保存:
mysql> exit
Bye
>>> mysql -u root -p
Enter password:
mysql> use test;
Database changed
mysql> select * from user;
Empty set (0.00 sec)
mysql>
如果我们不退出, 而是输入COMMIT; 时, 那么此时数据才真正保存到 MySQL 中:
mysql> commit;
Query OK, 0 rows affected (0.02 sec)
mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.13-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000001 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 219 | Query | 1 | 291 | BEGIN |
| mysql-bin.000001 | 291 | Table_map | 1 | 342 | table_id: 108 (test.user) |
| mysql-bin.000001 | 342 | Write_rows | 1 | 394 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000001 | 394 | Xid | 1 | 425 | COMMIT /* xid=58 */ |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
7 rows in set (0.00 sec)
从上面的操作中我们可以看到, 当禁用了 AUTOCOMMIT 后, 我们对数据库的写入操作并不会实际落地到数据库中, 除非我们显示地提交事务.
接下来, 我们使能 AUTOCOMMIT, 再次进行相同的操作.
mysql> set autocommit=1;
mysql> SHOW VARIABLES LIKE 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)
然后插入一个数据:
mysql> INSERT INTO user (`id`, `name`, `age`) VALUES (1, 'xys', 18);
接着查看数据:
mysql> select * from user;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | xys | 18 |
+----+------+------+
1 row in set (0.00 sec)
数据库中可以查询到这条数据了.
我们再次查看 binlog, 对比一下和禁用 AUTOCOMMIT 时有什么差别:
mysql> show binlog events;
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.13-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000001 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 219 | Query | 1 | 291 | BEGIN |
| mysql-bin.000001 | 291 | Table_map | 1 | 342 | table_id: 108 (test.user) |
| mysql-bin.000001 | 342 | Write_rows | 1 | 394 | table_id: 108 flags: STMT_END_F |
| mysql-bin.000001 | 394 | Xid | 1 | 425 | COMMIT /* xid=292 */ |
+------------------+-----+----------------+-----------+-------------+---------------------------------------+
7 rows in set (0.00 sec)
我们看到, 和禁用 AUTOCOMMIT 不同的是, 使能 AUTOCOMMIT 时, 每个写操作都会进行事务的提交. 即上面的 insert 操作等效为:
BEGIN;
INSERT INTO user (`id`, `name`, `age`) VALUES (1, 'xys', 18);
COMMIT;
004 --Mysql中的锁的问题的更多相关文章
- MySQL系列(五)---总结MySQL中的锁
MySQL中的锁 目录 MySQL系列(一):基础知识大总结 MySQL系列(二):MySQL事务 MySQL系列(三):索引 MySQL系列(四):引擎 概述 MyISAM支持表锁,InnoDB支持 ...
- MySQL中InnoDB锁不住表的原因
MySQL中InnoDB锁不住表是因为如下两个参数的设置: mysql> show variables like '%timeout%'; +-------------------------- ...
- MySQL中的锁、隔离等级和读场景
一.导言 关于MySQL中的锁还有隔离等级这类话题,其概念性的解释早已泛滥.记住其概念,算不上什么.更重要的是思考:他们的区别和联系在哪儿,为什么会有这样的概念. 1)MySQL的锁(Lock)分为行 ...
- MySQL实战 | 06/07 简单说说MySQL中的锁
原文链接:MySQL实战 | 06/07 简单说说MySQL中的锁 本文思维导图:https://mubu.com/doc/AOa-5t-IsG 锁是计算机协调多个进程或纯线程并发访问某一资源的机制. ...
- mysql中的锁表语句查看方法汇总
mysql> show status like 'Table%'; +----------------------------+----------+ | Variable_name | Val ...
- 你了解MySQL中的锁吗?
MySQL中的锁,分为全局锁.表级锁.行锁 全局锁 全局锁的意思就是,对整个数据库实例加锁,它的命令是FTWRL Flash tables with read lock 这个命令的语义是,使整个库处于 ...
- 谈谈MySQL中的锁
谈谈MySQL中的锁 锁的定义 在生活中锁的例子就非常多了,所以应该很容易理解锁的含义.在计算机领域,可以这样来概述,锁是计算机协调多个进行进程并发访问某一资源的机制. 在数据库中,锁也是一个 ...
- MySQL中的锁(表锁、行锁)
锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...
- mysql中的锁
MYSQL不同的存储引擎支持不同的锁的机制 MyISAM 支持表锁,InnoDB支持表锁和行锁 表锁,行锁比较 表锁:开销小,加锁快:不会出现死锁:锁定力度大,发生锁冲突概率高,并发度最低 行锁:开销 ...
随机推荐
- 自定义input[type="checkbox"]的样式
对复选框自定义样式,我们以前一直用的脚本来实现,不过现在可以使用新的伪类 :checkbox 来实现. 如果直接对复选框设置样式,那么这个伪类并不实用,因为没有多少样式能够对复选框起作用.不过,倒是可 ...
- python第十六课——外部函数and内部函数
1.外部函数&内部函数 内部函数: 定义在某个函数的内部,就是内部函数: [注意事项]: 1).内部函数可以随意使用它外部函数中的内容 2).外部函数不能使用内部函数中的内容 3).内部函数不 ...
- 在Ubuntu Desktop中安装软件
1. 安装好虚拟机后,可以先打开firefox,看是否可以访问外部的网页. 2. 如果在公司内网,可能访问不起,需要添加代理,确保可以访问外部的网页. 3. 更新软件源 sudo apt update ...
- 使用jenkins管理uirecorder录制的任务
在uirecorder官网(http://uirecorder.com/)上,对jenkins的配置只有简单的几句话: How to dock Jenkins? Add commands source ...
- 【2016蓝桥杯省赛】试题C++ B组试题
一. 煤球数目 作答:171700 #include <iostream> using namespace std; int main() { ,x=; ;i<=;i++){ ...
- 使用nginx替换Ingress
总感觉k8s Ingress 不可控, 所以使用nginx 替换Ingress,还是比较简单的. apiVersion: extensions/v1beta1 kind: DaemonSet meta ...
- salt常用命令(一)
查看模块包含哪些函数 salt 'node' sys.list_functions test 查看函数的用法 salt 'node' sys.doc test.echo 使用模块中的函数 salt ' ...
- selenium3驱动IE浏览器设置
前言: 使用selenium3+IE11的方式进行自动化测试 准备工作: 1.ie的驱动:IEDriverServer.exe(对应系统位数) 2.已安装好python3.selenium所需的相关服 ...
- 专家PID控制
1.专家PID控制原理 PID专家控制的实质是,基于受控对象和控制规律的各种知识,无需知道被控对象的精确模型,利用专家经验来设计PID参数.专家PID控制是一种直接型专家控制器. 典型的二阶系统单位阶 ...
- 二进制包 vs. 源代码包
在ROS中, 我们可能经常会遇到缺少相关的ROS依赖的问题. 有些时候你编译或者运行一些ROS程序, 系统会提示找不到XXX功能包. 如果是缺少ROS的依赖, 通常可以用以下命令来安装: $ sudo ...