首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
h2
微服务
router
php
php框架
stdout
memcache
sftp
smtp
uuid
phpunit
爬虫
localhost
cron
thinkphp
ftp
service
rabbitmq
iis
timezone
java
transform
interface
rust
nodejs
mysql
webserver
makefile
vb
tengine
struct
上传
pipeline
yaf
spring
protocol-buffers
php水印
dns
pipe
cookies
yii
hashmap
port
http2
mvc
cookie
python
cPlusPlus
正则
webhooks
web3
nginx
ssl
golang
django
gcc
lavarel
x86
queue
varnish
server
php5
lua
laravel
ci
upload
cache
压力测试
mqtt
openssl
caching
gzip
mq
pdo
crash
storage
token
asp.net
log4j
当前位置:
开发笔记
>
后端
> 正文
分析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
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
mysql
PHP 编程疑难解析与知识点汇总
本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ...
[详细]
蜡笔小新 2024-12-28 12:22:34
mysql
周期性出现的时间戳字段异常问题
探讨一个老旧 PHP MySQL 系统中,时间戳字段不定期出现异常值的问题及其可能原因。 ...
[详细]
蜡笔小新 2024-12-28 11:46:54
mysql
Dockerfile 编写与 Docker 网络配置详解
本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ...
[详细]
蜡笔小新 2024-12-27 17:31:41
mysql
MyBatis 动态 SQL 详解与应用
本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ...
[详细]
蜡笔小新 2024-12-27 16:20:10
mysql
解决PHP与MySQL连接时出现500错误的方法
本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ...
[详细]
蜡笔小新 2024-12-27 15:48:52
mysql
开源软件:新时代的商业机遇与挑战
在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ...
[详细]
蜡笔小新 2024-12-27 14:49:56
mysql
探索适用于Spring Boot的Web版SQL管理工具
本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ...
[详细]
蜡笔小新 2024-12-27 14:21:10
mysql
网站与MySQL数据库的连接与交互
本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ...
[详细]
蜡笔小新 2024-12-27 14:09:23
mysql
Windows 系统下 MySQL 8.0.11 的安装与配置
本文详细介绍了在 Windows 操作系统中安装和配置 MySQL 8.0.11 的步骤,包括环境准备、安装过程以及后续配置,帮助用户顺利完成数据库的部署。 ...
[详细]
蜡笔小新 2024-12-27 13:16:32
mysql
优化MySQL InnoDB的IO性能:配置参数详解
本文深入探讨了如何通过调整InnoDB的关键配置参数来优化MySQL的随机IO性能,涵盖了缓存、日志文件、预读机制等多个方面,帮助读者全面提升数据库系统的性能。 ...
[详细]
蜡笔小新 2024-12-27 13:00:29
mysql
MySQL数据库安装指南
本文详细介绍如何下载并安装MySQL数据库(5.7.10版本),以及配置Navicat管理工具(免费版)。通过本指南,您将了解从下载到安装的完整流程,并掌握基本的数据库管理技能。 ...
[详细]
蜡笔小新 2024-12-27 10:53:40
mysql
MySQL中枚举类型的所有可能值获取方法
本文介绍了一种在MySQL数据库中查询枚举(ENUM)类型字段所有可能取值的方法,帮助开发者更好地理解和利用这一数据类型。 ...
[详细]
蜡笔小新 2024-12-27 10:36:44
mysql
如何设计关系型数据库以有效记录设备的上下线历史
本文探讨了在处理大量物联网设备时,如何合理设计关系型数据库来高效记录设备的上下线历史,确保数据的可维护性和扩展性。 ...
[详细]
蜡笔小新 2024-12-27 10:31:31
mysql
MySQL 用户创建失败的解决方案
本文详细介绍了在 MySQL 中遇到用户创建失败问题时的解决方法,包括如何正确配置环境、执行命令以及常见错误排查技巧。通过逐步指导,帮助用户顺利添加和管理 MySQL 用户。 ...
[详细]
蜡笔小新 2024-12-27 09:28:52
mysql
启动MySQL服务的命令行步骤
本文详细介绍了如何通过命令行启动MySQL服务,包括打开命令提示符窗口、进入MySQL的bin目录、输入正确的连接命令以及注意事项。文中还提供了更多相关命令的资源链接。 ...
[详细]
蜡笔小新 2024-12-26 20:16:36
哦呦喂酿
这个家伙很懒,什么也没留下!
Tags | 热门标签
h2
微服务
router
php
php框架
stdout
memcache
sftp
smtp
uuid
phpunit
爬虫
localhost
cron
thinkphp
ftp
service
rabbitmq
iis
timezone
java
transform
interface
rust
nodejs
mysql
webserver
makefile
vb
tengine
RankList | 热门文章
1
按某些字母拆分字符串同时跳过某些字母
2
安装react环境(一)Node.js安装流程
3
详解golang 模板(template)的常用基本语法
4
站长工具的JS混淆加密压缩后是怎么用的?
5
Java 中 linkedblockingdequetaklast()方法
6
九度OJ 城际公路网 图论
7
暑期旅游途中的美容妙法
8
Java多线程 5.栅栏
9
一文读懂 ChIPseq
10
启动服务提供者报 zookeeper not connected错
11
NT5.X/NT6.0双启动的故障解决
12
这座城市多了十只伤心的鸽
13
【数据结构】栈(stack)栈链(动图解、c++、java)
14
hplaserjet1020插上usb之后电脑一直响
15
静态方法如何在Kotlin项目中实现
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有