欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《深入浅出MySQL学习笔记-事务控制、锁定语句及分布式事务》

程序员文章站 2024-01-05 10:48:40
...

默认情况下,行锁和表锁都是自动获得,不需要额外的命令,但有些情况用户需要明确的进行锁表或者事务控制,以保证整个事务完整性。

引擎 特点
MyISAM、MEMORY 表级锁 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
BDB 页级锁定 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
InnoDB 行级锁定 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

14.1 LOCK TABLE和UNLOCK TABLE
LOCK TABLE能锁定用于当前线程的表,如果表被其他线程锁定,当前线程会等待直到所由锁定为止。
UNLOCK TABLE可以释放当前线程获得的任何锁定,当前线程执行另一个LOCK TABLE时或当服务器连接关闭时,所有当前线程锁定的表被隐含地解锁。
eg: LOCK TABLES tablename [as t] {READ [LOCAL]|[LOW_PRIORITY]WRITE} [,tablename2 …]
UNLOCK TABLES
排它锁:也称独占锁、写锁或X锁,若sessionA获得某数据表的排他锁权限,那么sessionA只能对该表进行读取或修改,其他session既不能读取也不能修改该表,更不能对该表加任何类型的锁,直到sessionA释放排它锁权限。加锁方式:lock tables tablename write;
共享锁:也称读锁或S锁,若sessionA获得某数据表的共享锁权限,那么任何session(包括sessionA)只能对该表进行读取,不能修改该表,sessionA可以继续对该数据表加X锁,其他session可以对该数据表继续加S锁但不能加X锁,直到sessionA释放共享锁权限。加锁方式:lock tables tablename read;

14.2 事务控制
MYSQL通过一下语句支持本地事务:
START TRANSCATION | BEGIN [WORK] #开始一项新事务
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]#提交事务,CHAIN会立即启动一个新事务,release会断开和服务器的连接
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO]RELEASE]#回滚事务
SET AUTOCOMMIT={0|1}#修改提交方式,如果设置为0则需手动提交
默认情况下 MySQL是自动提交的,若需要明确的commit和rollback来提交和回滚事务,那就需要明确的事务控制命令来开始事务。
如果在锁表期间用START TRANSACTION 命令开始一个新事务,会造成一个隐含的unlock tables被执行。因此在用一个事务中最好不用不同引擎的表,否则ROLLBACK时需要对非事务性的表进行特别处理,因为COMMIT, ROOLBACK只能对事务类型表进行提交和回滚。
通常只对提交的事务记录到二进制的日志中,但如果一个事物中包含飞事务类型的表,则回滚操作记录也会被记录到二进制日志中,确保非事务类型表的更新可以被复制到从数据库中。
在事务中可以通过定义SAVEPOINT,指定回滚事务的一个部分,但不能指定提交事务的一个部分,对复杂的应用可定义多个不同的SAVEPOINT来满足不同条件下的回滚。
定义SAVEPOINT: SAVEPOINT test;
删除SAVEPOINT: RELEASE SAVEPOINT test

14.3.1 分布式事务的原理
MySQL使用分布式事务应用程序涉及一个或多个资源管理器和事务管理器。
资源管理器RM用于提供通向事务资源的途径,数据库服务器是一种资源管理器,他必须可以提交或回滚RM管理的事务。
事务管理器TM用于协调作为一个分布式事务一部分的事务,TM与管理每个事务的RMs通信,在一个分布式事务中,单个事务均是分布式事务的分支事务。分布式事务和各分支通过一种命名方法进行标识。
MySQL执行XA MySQL时,MySQL服务器相当于一个用于管理分布式事务的资源管理器。与MySQL服务器连接的客户端相当于事务管理器。
执行分布式事务过程分两阶段提交,发生时间在由分布式事务各个分支进行的行动已被执行之后。
一阶段:所有分支预备好,他们被TM告知要准备提交,通常意味着用于管理分支的每个RM会记录对于被稳定保存的分支的行动。
二阶段:TM告知RMs是否要提交或回滚,如果在预备分支时所有的分支指示他们能提交,则所有的分支被告知要提交,若预备时有任何分支指示他不能提交,则所有分支被告知回滚。
14.3.2 分布式事务的语法
xid是一个XA事务标识符,xid :gtrid [,bqual [, formatID]],gtrid是一个分布式事务标识符,相同分布式事务应该适应相同的gtrid,这样可以明确知道XA事务属于哪个分布式事务。bqual是一个分支限定符,默认值时空串,对于一个分布式事务中的每个分支事务,bqual值必须是唯一的。formatID是一个数字,用于表示gtrid和bqual值使用的格式,默认值为1.下面为常用分布式事务语法:

(1)XA {START|BEGIN}xid [JIOIN|RESUME]#启动带给定xid值的XA事务

(2)XA END xid [SUSPEND [FOR MIGRATE]]#此处end是进入IDLE状态
XA PREPARE xid#使事务进入PREPARE状态,此为提交的第一阶段

(3)XA COMMIT xid [ONE PHASE]#提交具体事务
XA ROLLBACK xid#回滚具体事务
XA RECOVER#返回当前数据库中处于PREPARE状态的分支事务的详细信息

分布式的关键在于如何确保分布式事务的完整性,以及某分支出现问题时的故障解决。

14.3.3 存在的问题
若分支事务达到prepare状态时,数据库异常超重新启动服务器重新启动以后,可以继续对分支事务进行提交或者回滚操作,但是提交的事务没写binlog,存在一定隐患可能导致使用binlog恢复丢失部分数据。
如果分支事务的客户端连接异常终止,那么数据库恢自动回滚未完成的分支事务,如果此时分支事务已经执行到prepare状态,那么这个分布式事务的其他分支可能已经成功提交,如果某个分支回滚,可能导致分布式事务的不完整,丢失部分分支事务的内容。
如果分支事务在执行到prepare状态时,数据库异常且不能正常启动,需要使用备份和binlog来恢复数据,那么在prepare状态的分支事务因为并没有记录到binlog,所以不能通过binlog进行恢复,数据库恢复后将丢失这部分数据。

总之:MySQL分布式事务还存在较严重缺陷,在数据库或应用异常情况先可能导致分布式事务不完整,,根据实际对数据完整性的要求可选择是否使用。

上一篇:

下一篇: