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支持表锁和行锁 表锁,行锁比较 表锁:开销小,加锁快:不会出现死锁:锁定力度大,发生锁冲突概率高,并发度最低 行锁:开销 ...
随机推荐
- PHP常用符号和函数
(转)最近在写PHP程序的时候发现了一些特殊的PHP符号,例如连续小于符号,三个小于符号,eot,eod,echo示例,print示例等,突然间 发现用这么久的PHP了,竟然连PHP的基本符号都没有认 ...
- Latex排版全解
Latex排版全解 LATEX(英语发音:/ˈleɪtɛk/ LAY-tek或英语发音:/ˈlɑːtɛk/ LAH-tek,音译“拉泰赫”),是一种基于TEX的排版系统,由美国电脑学家莱斯利•兰伯特在 ...
- linux shell基本知识 sleep命令
在有的shell(比如linux中的bash)中sleep还支持睡眠(分,小时) sleep 睡眠1秒 sleep 1s 睡眠1秒 sleep 1m 睡眠1分 sleep 1h 睡眠1小时
- HDU 1257 最少拦截系统(贪心 or LIS)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 最少拦截系统 Time Limit: 2000/1000 MS (Java/Others) ...
- 50个国内外最棒的C/C++源码站点分享
C/C++是最基本的编程语言.这里列出了50名优秀站点和网页清单,这些站点提供c/c++源码.这份清单提供了源码的链接以及它们的小说明.我已 尽力包含最佳的C/C++源码的站点.这不是一个完整的清单, ...
- python-greenlet模块(协程)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from greenlet import greenlet def test1(): print(12) ...
- 基于vue-cli的快速开发框架
基于vue-cli的快速规范开发框架,已封装常用组件,可直接进行基本项目开发 1,遵循eslint规则,提升代码质量 2,集成mock模拟服务端数据,提升开发效率 3,集成vuex,可直接使用开发 4 ...
- ThinkPhp5学习之新手博客
前端框架来源网络,后端框架采用 ThinkPhp 5 开发 参考资料:哔哩哔哩 ThinkPHP5.1新手博客项目实战 项目地址:https://github.com/yjy1/tp5
- jQuery----初识jQuery
一.jQuery好处: ①写得少,做的多 ②链式编程 ③隐式迭代 ④解决兼容性问题 二.顶级对象 Dom中的顶级对象:document------>页面中的顶级对象 document.点出来的是 ...
- 【转】Win10/UWP新特性系列—Web
Internet Explorer Internet Explorer 在Windows 10 升级为Edge模式,是一种交互性和兼容性都很强的新型浏览器,该浏览器相比以前的版本更新了超过2000个操 ...