首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
cookies
cache
package
webhooks
ftp
base64
hashmap
yaf
server
tengine
static
织梦cms
interface
wordpress
struct
nodejs
frontend
rabbitmq
iis
queue
laravel
ruby
swoole
爬虫
http2
api
x86
sms
php
curl
分布式
mqtt
php框架
php水印
sockets
pip
storage
cPlusPlus
rust
http
cookie
stdout
cron
php绘图
spring
touch
thinkphp
并发
上传
openssl
mysql
smtp
mvc
ffmpeg
token
pipe
timeout
h2
c语言
多线程
asp.net
ssl
memcache
localhost
mq
lua
gzip
cSharp
缓存
webserver
crash
caching
uuid
phpunit
node.js
grpc
python
protocol-buffers
syslog
当前位置:
开发笔记
>
后端
> 正文
分析MySQ锁机制和事务控制
作者:哦呦喂酿 | 来源:互联网 | 2014-04-08 01:34
innodb_lock_wait_timeout系统变量的值来解决这些情况。如果要依靠锁等待超时来解决死锁问题,对于更新事务密集的应用,将有可能导致大量事务的锁等待,导致系统异常,所以不推荐在一个事务中混合更新不同存储类型的表,也不推荐相同类型的表采用不同的锁定方式加锁
一、如何加锁
锁定表的语法:
LOCK TABLES
tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}
[, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ...
解锁语法:
UNLOCK TABLES
innodb的存储引擎提供行级锁,支持共享锁和排他锁两种锁定模式,以及四种不同的隔离级别。
二、死锁
InnoDB自动检测事务的死锁,并回滚一个或几个事务来防止死锁。InnoDB不能在MySQL LOCK TABLES设定表锁定的地方或者涉及InnoDB之外的存储引擎设置锁定的地方检测死锁。你必须通过设定innodb_lock_wait_timeout系统变量的值来解决这些情况。如果要依靠锁等待超时来解决死锁问题,对于更新事务密集的应用,将有可能导致大量事务的锁等待,导致系统异常,所以不推荐在一个事务中混合更新不同存储类型的表,也不推荐相同类型的表采用不同的锁定方式加锁。
三、事务控制
MySQL通过SET AUTOCOMMIT, START TRANSACTION, COMMIT和ROLLBACK等语句支持本地事务。语法:
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}
默认情况下,mysql是autocommit的,如果需要通过明确的commit和rollback来提交和回滚事务,那么需要通过明确的事务控制命令来开始事务,这是和oracle的事务管理明显不同的地方,如果应用是从oracle数据库迁移到mysql数据库,则需要确保应用中是否对事务进行了明确的管理。
①START TRANSACTION或BEGIN语句可以开始一项新的事务。
②COMMIT和ROLLBACK用来提交或者回滚事务。
③CHAIN和RELEASE子句分别用来定义在事务提交或者回滚之后的操作,chain会立即启动一个新事物,并且和刚才的事务具有相同的隔离级别,release则会断开和客户端的连接。
④SET AUTOCOMMIT可以修改当前连接的提交方式,如果设置了SET AUTOCOMMIT=0,则设置之后的所有事务都需要通过明确的命令进行提交或者回滚。
如果我们只是对某些语句需要进行事务控制,则使用START TRANSACTION开始一个事务比较方便,这样事务结束之后可以自动回到自动提交的方式,如果我们希望我们所有的事务都不是自动提交的,那么通过修改AUTOCOMMIT来控制事务比较方便,这样不用在每个事务开始的时候再执行START TRANSACTION。
time
session_1
session_2
--------------------------------------------------------->
mysql> select * from tt3;
Empty set (0.00 sec)
mysql> select * from tt3;
Empty set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tt3 values('1',1);
Query OK, 1 row affected (0.03 sec)
mysql> select * from tt3;
Empty set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.05 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 1 | 1.00 |
+------+------+
1 row in set (0.00 sec)
mysql> insert into tt3 values('2',2);
Query OK, 1 row affected (0.04 sec)
这个事务是按照自动提交执行的
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 1 | 1.00 |
| 2 | 2.00 |
+------+------+
2 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into tt3 values('3',3);
Query OK, 1 row affected (0.00 sec)
mysql> commit and chain;
Query OK, 0 rows affected (0.05 sec)
自动开始一个新的事务
mysql> insert into tt3 values('4',4);
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 1 | 1.00 |
| 2 | 2.00 |
| 3 | 3.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.06 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 1 | 1.00 |
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
4 rows in set (0.00 sec)
开始一个事务,会造成一个隐含的unlock tables被执行:
time
session_1
session_2
--------------------------------------------------------->
mysql> select * from tt3;
Empty set (16.65 sec)
mysql> select * from tt3;
Empty set (16.65 sec)
mysql> lock table tt3 write;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tt3;
等待
mysql> insert into tt3 values('1',1);
Query OK, 1 row affected (0.07 sec)
等待
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
等待
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
等待
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 1 | 1.00 |
+------+------+
1 row in set (37.71 sec)
开始一个事务时,表锁被释放。
对lock方式加的表锁,不能通过rollback进行回滚。
因此,在同一个事务中,最好不使用不同存储引擎的表,否则rollback时需要对非事务类型的表进行特别的处理,因为commit、rollback只能对事务类型的表进行提交和回滚。
通常情况下,只对提交的事务纪录到二进制的日志中,但是如果一个事务中包含非事务类型的表,那么回滚操作也会被记录到二进制日志中,以确保非事务类型表的更新可以被复制到从的数据库中。
和oracle的事务管理相同,所有的DDL语句是不能回滚的,并且部分的DDL语句会造成隐式的提交。
在事务中可以通过定义savepoint,指定回滚事务的一个部分,但是不能指定提交事务的一个部分。对于复杂的应用,可以定义多个不同的savepoint,满足不同的条件时,回滚不同的savepoint。需要注意的是,如果定义了相同名字的savepoint,则后面定义的savepoint会覆盖之前的定义。对于不再需要使用的savepoint,可以通过release savepoint命令删除savepoint,删除后的savepoint,不能再执行rollback to savepoint命令。
下面我们例子就是模拟回滚事务的一个部分,通过定义savepoint来指定需要回滚的事务的位置。
time
session_1
session_2
--------------------------------------------------------->
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from tt3 where id = '2';
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> savepoint test;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from tt3 where id = '3';
Query OK, 1 row affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> rollback to savepoint test;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 2 | 2.00 |
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
3 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.05 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from tt3;
+------+------+
| id | name |
+------+------+
| 3 | 3.00 |
| 4 | 4.00 |
+------+------+
2 rows in set (0.00 sec)
mysql
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
php
周期性出现的时间戳字段异常问题
探讨一个老旧 PHP MySQL 系统中,时间戳字段不定期出现异常值的问题及其可能原因。 ...
[详细]
蜡笔小新 2024-12-28 11:46:54
server
Deepin系统下MySQL 5.7安装指南
本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ...
[详细]
蜡笔小新 2024-12-28 10:48:41
server
MyBatis 动态 SQL 详解与应用
本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ...
[详细]
蜡笔小新 2024-12-27 16:20:10
php
解决PHP与MySQL连接时出现500错误的方法
本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ...
[详细]
蜡笔小新 2024-12-27 15:48:52
php
开源软件:新时代的商业机遇与挑战
在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ...
[详细]
蜡笔小新 2024-12-27 14:49:56
php
探索适用于Spring Boot的Web版SQL管理工具
本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ...
[详细]
蜡笔小新 2024-12-27 14:21:10
php
网站与MySQL数据库的连接与交互
本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ...
[详细]
蜡笔小新 2024-12-27 14:09:23
php
Windows 系统下 MySQL 8.0.11 的安装与配置
本文详细介绍了在 Windows 操作系统中安装和配置 MySQL 8.0.11 的步骤,包括环境准备、安装过程以及后续配置,帮助用户顺利完成数据库的部署。 ...
[详细]
蜡笔小新 2024-12-27 13:16:32
php
优化MySQL InnoDB的IO性能:配置参数详解
本文深入探讨了如何通过调整InnoDB的关键配置参数来优化MySQL的随机IO性能,涵盖了缓存、日志文件、预读机制等多个方面,帮助读者全面提升数据库系统的性能。 ...
[详细]
蜡笔小新 2024-12-27 13:00:29
php
MySQL数据库安装指南
本文详细介绍如何下载并安装MySQL数据库(5.7.10版本),以及配置Navicat管理工具(免费版)。通过本指南,您将了解从下载到安装的完整流程,并掌握基本的数据库管理技能。 ...
[详细]
蜡笔小新 2024-12-27 10:53:40
php
MySQL中枚举类型的所有可能值获取方法
本文介绍了一种在MySQL数据库中查询枚举(ENUM)类型字段所有可能取值的方法,帮助开发者更好地理解和利用这一数据类型。 ...
[详细]
蜡笔小新 2024-12-27 10:36:44
php
如何设计关系型数据库以有效记录设备的上下线历史
本文探讨了在处理大量物联网设备时,如何合理设计关系型数据库来高效记录设备的上下线历史,确保数据的可维护性和扩展性。 ...
[详细]
蜡笔小新 2024-12-27 10:31:31
server
MySQL 用户创建失败的解决方案
本文详细介绍了在 MySQL 中遇到用户创建失败问题时的解决方法,包括如何正确配置环境、执行命令以及常见错误排查技巧。通过逐步指导,帮助用户顺利添加和管理 MySQL 用户。 ...
[详细]
蜡笔小新 2024-12-27 09:28:52
php
启动MySQL服务的命令行步骤
本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ...
[详细]
蜡笔小新 2024-12-26 20:16:36
cache
解读MySQL查询执行计划的详细指南
本文旨在帮助开发者和数据库管理员深入了解如何解读MySQL查询执行计划。通过详细的解析,您将掌握优化查询性能的关键技巧,了解各种访问类型和额外信息的含义。 ...
[详细]
蜡笔小新 2024-12-26 20:10:30
哦呦喂酿
这个家伙很懒,什么也没留下!
Tags | 热门标签
cookies
cache
package
webhooks
ftp
base64
hashmap
yaf
server
tengine
static
织梦cms
interface
wordpress
struct
nodejs
frontend
rabbitmq
iis
queue
laravel
ruby
swoole
爬虫
http2
api
x86
sms
php
curl
RankList | 热门文章
1
Java Eclipse IDE 中新编写的函数变量解析失败的原因分析与解决方法
2
YOLO V3 Pytorch 实战教程 Part 4:深入解析置信度阈值与非极大值抑制技术
3
阿里巴巴Java后端开发面试:TCP、Netty、HashMap、并发锁与红黑树深度解析
4
深入解析Google Guava库中的Optional类及其应用场景
5
H3C防火墙自动构建安全隧道
6
深入解析Android事件分发机制源代码
7
Eclipse环境下Spring框架源码部署的实战心得与技术解析
8
Struts2进阶指南:实现自定义拦截器详解
9
优化Spring Cloud Zuul与Nginx域名转发问题的解决方案_java
10
微软发布紧急安全更新,所有Windows 10版本均面临影响!
11
Linux 系统初始化启动流程详解
12
如何在DataGridView中实现带有图标的单元格显示
13
正则表达式与文本处理三剑客深入解析
14
深入解析 Super 关键字的用法与应用场景
15
未正确关闭InputStream引发Tomcat异常终止,重启后出现java.io.EOFException错误
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有