首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
nginx
正则
yii
package
python
router
http
rust
tengine
sftp
mq
hashmap
varnish
并发
pdo
go
protocol-buffers
cpython
makefile
lavarel
cookie
spring
session
uuid
ffmpeg
syslog
c语言
ssl
base64
pipeline
storage
openssl
pip
分布式
phpmyadmin
队列
crontab
lvs
port
timeout
interface
ci
x86
爬虫
cron
pipe
pymongo
grpc
h2
webhooks
transform
swoole
ftp
ruby
golang
mvc
php水印
timezone
vb
rabbitmq
phpunit
lua
queue
caching
iis
curl
redis
thinkphp
service
php
mqtt
微服务
http2
laravel
touch
stdout
缓存
log4j
smtp
当前位置:
开发笔记
>
后端
> 正文
分析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
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
ssl
java类名的作用_java下Class.forName的作用是什么,为什么要使用它?
湖上湖返回与带有给定字符串名的类或接口相关联的Class对象。调用此方法等效于:Class.forName(className,true,currentLoader) ...
[详细]
蜡笔小新 2024-11-20 12:55:32
ssl
Logging all MySQL queries into the Slow Log
MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ...
[详细]
蜡笔小新 2024-11-20 12:50:01
python
MySQL中批量删除特定前缀表的方法
在MySQL数据库管理中,有时需要批量删除具有相同前缀的表。由于MySQL本身并未提供直接支持此操作的工具,因此需要利用SQL查询来构造DROP TABLE语句,以实现这一需求。 ...
[详细]
蜡笔小新 2024-11-19 15:29:31
并发
Swoole 中 WorkerStart 创建的对象如何实现多客户端隔离
探讨在 Swoole 的 WorkerStart 回调中创建的对象如何在多个客户端之间实现隔离,确保每个客户端的数据独立性。 ...
[详细]
蜡笔小新 2024-11-19 14:58:13
ssl
如何在U8系统中连接服务器并获取数据
本文介绍了如何在U8系统中通过不同的方法连接服务器并获取数据,包括使用MySQL客户端连接实例的方法,如非SSL连接和SSL连接,并提供了详细的步骤和注意事项。 ...
[详细]
蜡笔小新 2024-11-19 12:08:19
ssl
mysql数据库json类型数据,sql server json数据类型
mysql数据库json类型数据,sql server json数据类型 ...
[详细]
蜡笔小新 2024-11-19 11:05:28
go
解决Win7系统下MySQL安装时的安全设置应用失败问题
本文详细探讨了在Windows 7操作系统中安装MySQL时遇到的‘安全设置无法应用于数据库’错误的解决方案。通过逐步指导和专业建议,帮助用户顺利解决这一常见问题。 ...
[详细]
蜡笔小新 2024-11-19 10:23:20
http
在 Ubuntu 22.04 LTS 上部署 Jira 敏捷项目管理工具
Jira 敏捷项目管理工具专为软件开发团队设计,旨在以高效、有序的方式管理项目、问题和任务。该工具提供了灵活且可定制的工作流程,能够根据项目需求进行调整。本文将详细介绍如何在 Ubuntu 22.04 LTS 上安装和配置 Jira。 ...
[详细]
蜡笔小新 2024-11-19 09:56:22
session
构建用户画像环境:Hive与SparkSQL的高效整合
本文介绍如何通过整合SparkSQL与Hive来构建高效的用户画像环境,提高数据处理速度和查询效率。 ...
[详细]
蜡笔小新 2024-11-19 09:44:24
pdo
如何处理PHP缺少扩展的问题
本文将详细介绍如何解决PHP环境中缺少扩展的问题,包括检查当前环境、修改配置文件以及验证修改是否生效的具体步骤,帮助开发者更好地管理和使用PHP扩展。 ...
[详细]
蜡笔小新 2024-11-19 09:19:01
go
MySQL InnoDB 存储引擎中的事务机制及日志详解
本文详细介绍了 MySQL InnoDB 存储引擎的事务机制,包括 ACID 特性、redo 日志、undo 日志以及 checkpoint 的作用和实现方式。 ...
[详细]
蜡笔小新 2024-11-18 20:22:02
spring
spring(22)JdbcTemplate
2019独角兽企业重金招聘Python工程师标准###1.导入jar包,必须jar包:c3p0、mysql-connector、beans、con ...
[详细]
蜡笔小新 2024-11-18 19:49:32
spring
MySQL 使用复合主键时索引的使用情况分析
在 MySQL 中使用复合主键时,每个主键字段是否都能使用索引?本文通过实验验证了这一问题,并提供了详细的解释和建议,以帮助开发者避免因不当使用索引而导致的性能问题。 ...
[详细]
蜡笔小新 2024-11-18 18:27:39
spring
mysql 授权!!
为什么80%的码农都做不了架构师?MySQL的权限系统围绕着两个概念:认证-确定用户是否允许连接数据库服务器授权-确定用户是否拥有足够的权限执 ...
[详细]
蜡笔小新 2024-11-18 17:34:42
go
开发笔记:[14]SQL 别名
开发笔记:[14]SQL 别名 ...
[详细]
蜡笔小新 2024-11-18 15:34:08
哦呦喂酿
这个家伙很懒,什么也没留下!
Tags | 热门标签
nginx
正则
yii
package
python
router
http
rust
tengine
sftp
mq
hashmap
varnish
并发
pdo
go
protocol-buffers
cpython
makefile
lavarel
cookie
spring
session
uuid
ffmpeg
syslog
c语言
ssl
base64
pipeline
RankList | 热门文章
1
Java反射机制详解及应用场景
2
ExpressSession 设置 Cookie 失败的原因分析
3
Python 基础知识:每日进步的力量
4
Charles 工具使用指南与心得
5
基于iSCSI的SQL Server 2012群集测试(一)SQL群集安装
6
网络爬虫的规范与限制
7
异步 Rust 中的多线程为何无法实现并行化?
8
JUC(三):深入解析AQS
9
AngularJS $compile 详解
10
编写高质量jQuery插件的关键要点
11
如何在程序中实现鼠标悬停时的光标变化?
12
javax.mail.search.BodyTerm.matchPart()方法的使用及代码示例
13
ECharts 饼图动态数据加载与展示
14
JavaScript - 禁用HTML内容在Ctrl+F搜索中的高亮显示
15
Laravel 开发技巧:如何为集合中的每个元素添加递增编号
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有