mySql 事务控制和锁定语句

来源:互联网 发布:php后端服务器面试题 编辑:程序博客网 时间:2024/06/16 07:14

   LOCK TABLE 和 UNLOCK TABLE

         LOCK TABLES 可以锁定用于当前线程的表,如果表被其它线程锁定,则当前线程需等待,直到可以获取所有锁定为止。

        UNLOCK TABLES 可以释放当前线程获得的任何锁定,当前线程执行另一个LOCK TABLES或者当与服务器的连接被关闭时,所有由当前线程锁定的表被隐含地解锁。

        如果session1对表a进行锁表,则session1和其它session都可以进行锁表,但是在更新时,其它session需要等待session1对表a进行解锁,然后才能进行表的更新。

    事务控制

        mySql通过 SET AUTOCOMMIT,START TRANSACTION,COMMIT,ROLLBACK等语句支持本地事务。
        默认情况下,mySql是自动提交的(Autocommit),如果需要通过明确的Commit和Rollback来提交和回滚事务,那么需要通过明确地事务控制命令开始事务,,这是和Oracle数据库事务管理明显不同的地方。如果应用是从Oracle数据库迁移到mySql数据库,需要确保是否对事务进行了明确地管理。
        START TRANSACTION或BEGIN语句可以开始一项新的事务。
        COMMIT和ROLLBACK用来提交或者回滚事务。
        CHAIN和RELEASE子句分别用来定义在事务提交或者回滚之后的操作,CHAIN会立即启动一个新事物,并且和刚才的事务完全隔离而且具有相同的级别,RELEASE则会立即断开和客户端的连接
        SET AUTOCOMMIT 可以修改当前连接的提交方式,如果值为0,在设置之后所有事务都需要通过明确的命令进行提交或者回滚。
        如果只是对某些语句进行事务控制,则使用START TRANSACTION语句开始一个事务比较方便,事务结束之后可以自动回到自动提交的方式,如果希望所有事务都不是自动提交的,那么通过修改AUTOCOMMIT控制事务比较方便,不用在每个事务开始的时候执行 START TRANSACTION语句。
 如果在锁表期间,用start transaction 命令开始一个新事物,会造成一个隐含的unlock tables被执行,如表14-3

        在同一个事务中,最好不要使用不同存储引擎的表,否则ROLLBACK时需要对非事务类型的表进行特别的处理,因为COMMIT和ROLLBACK只能对事务类型的表进行提交和回滚。
        通常情况下,只对提交的事务记录到二进制日志中,但是如果一个事务中包含非事务类型的表,回滚操作也会被记录到二进制日志中,以确保非事务类型表的更新可以被复制到从(Slave)数据库中。
        在事务中,可以通过定义SAVEPOINT,指定回滚事务的一部分,但不能指定提交事务的一个部分,对于复杂的应用,可以定义多个不同的SAVEPOINT,满足不同的I傲剑时,回滚不同的SAVEPOINT,需要注意,如果定义了相同名字的SAVEPOINT,后面定义的SAVEPOINT]会覆盖之前的定义。对于不在需要的SAVEPOINT',可以通过RELEASE SAVEPOINT命令删除SAVEPOINT,删除后的SAVEPOINT,不能执行ROLLBACK TO SAVEPOINT命令。
        表14-4所示的例子就是模拟回滚事务的一个部分,通过定义SAVEPOINT来制定需要回滚的事务的位置。

    分布式事务的使用

        mySql从5.0.3开始支持分布式事务,当前分布式事务只支持InnoDB存储引擎,一个分布式事务会涉及多个行动,这些行动本身是事务性的,所有行动必须一起成功完成或者一起被回滚。

     分布式事务的原理

        在mySql中,使用分布式事务的应用程序涉及一个或多个或多个资源管理器和一个事务管理器。
        资源管理器(RM)用于提供通向事务资源的途径,数据库服务器是一种资源管理器,该管理器必须可以提交或回滚由RM管理的事务。
        事务管理器(TM)用于协调作为一个分布式事务一部分的事务,TM与管理每个事务的RMs进行通讯。一个分布式事务中各个单个事务均是分布式事务的"分支事务"。
        要执行衣蛾分布式事务,必须知道这个分布式事务设计到了哪些资源管理器,并把每个资源管理器的事务执行到事务可以被提交或者回滚时。这些分支事务必须作为一个原子性操作全部提交或回滚。要管理一个分布式事务,必须要考虑任何组件或连接网络可能会产生的故障。
        用于执行分布式事务的过程使用两阶段提交,发生时间在由分布式事务的各个分支需要进行的行动已经被执行之后。
        在第一阶段,所有的分支被预备好,他们被TM告知要准备提交,通常,这意味着管理分支的每个RM会记录对于被文帝呢保存的分支的行动。分支指示它们是否可以这样做结果将用于第二阶段。
        在第二阶段,TM告知RMs是否要提交或回滚,如果在预备分支时,所有分支指示它们将能够提交,则所有分支被告知提交。如果在预备时,有任何分支指示它将不能提交,则所有分支被告知回滚。有些情况下,一个分布式事务可能会使用一阶段提交。例如,当事务管理器,一个分布式事务只由一个事务资源组成(即单一分支),则该资源被告知可以同时进行预备和提交。

    分布式事务的语法

    XA {START|BEGIN} xid [JOIN|RESUME]
        XA START xid 用于启动一个带给定xid值的XA事务,每个XA事务必须有一个唯一的xid值,因此该值当前不能被其他的XA事务使用。每个XA事务必须有一个唯一的xid值,因此该值不能被其它XA事务使用。xid 是一个XA事务标识符,用来唯一标识一个分布式事务。xid值由客户端提供,或由meSql服务器生成,xid包含1~3个部分,
        gtrid 是一个分布式事务标识符,相同的分布式事务应该使用相同的gtrid,这样可以明确知道xa事务属于哪个分布式事务。
        bqual 是一个分支限定符,默认值是空串,对于一个分布式事务中的每个分支事务,bqual值必须是唯一的。
        formatID 是一个数字,用于标识有gtrid和bqual值所使用的格式,默认值为1.
    XA END xid [SUSPEND [FOR MIGRATE]]    XA PREPARE xid
        使事务进入PREPARE状态,也就是两阶段提交的第一个阶段。
    XA COMMIT xid [ONE PHASE]    XA ROLLBACK xid;
       这个两个命令用来提交或者回滚具体的分支事务,两阶段提交的第二个阶段,分支事务被实际提交或者回滚。
    XA RECOVER
        XA RECOVER返回当前数据库中处于PREPARE状态的分支事务的详细信息。
        分布式的关键在于如何确保分布式事务的完整性,以及在某个分支出现问题时的故障解决。XA 的相关命令就是提供给应用如何在多个独立的数据库之间进行分布式事务的管理,包括启动一个分支事务,使事务进入准备阶段以及事务的实际提交回滚操作。
        表14-5所示的例子演示了一个简单的分布式事务的执行,事务的内容时在DB1中插入一条记录,同时在DB2中更新一条记录,两个操作作为同一事物提交或者回滚。
        存在的问题,虽然mySql支持分布式事务,但还是存在一些问题,如果分支事务达到prepare状态时,数据库异常重新启动,服务器重新启动后,可以继续对分支事务进行提交或者回滚,但是提交的事务没有写binlog,存在一定隐患,可能导致使用binlog恢复丢失部分数据。如果存在复制的数据库,则有可能导致主从数据库的数据不一致,从表actor中查询first_name='Simon'的记录,有一条,
    select actor_id, last_name from actor where first_name='Simon';
        启动分布式事务" test" ,删除刚才查询的记录,
    xa start 'test';    执行后    deletet from actor where actor_id=301;     执行后    select actor_id, last_name from actor where first_name='Simon';     查询结果为空
        完成第一阶段提交,进入prepare状态,
    xa end 'test';    执行后    xa prepare 'test';
        此时数据库异常终止,查询出错,
    select actor_id, last_name from actor where first_name='Simon';
        启动数据库后,分支事务依然存在,
    xa recover \G
        表中记录并没有被删除,
    select actor_id, last_name from actor where first_name='Simon';
        可以进行提交或者回滚,
    xa commit 'test';
        使用mysqlbinlog查看binlog,可以取人最后提交的这个分支事务并没有记录到binlog中,应为赋值和灾难恢复都依赖于binlog,所以sinlog的缺失会导致复制环境的不同步,以及使用binlog恢复丢失部分数据。
        如果分支事务的客户端连接异常终止,数据库会自动回滚未完成的分支事务,如果此时的分支事务已经执行到prepare状态,这个分布式事务的其它分支可能已经成功提交,如果这个分支回滚,可能导致分布式事务的不完整,丢失部分分支事务的内容。
        表14-6 客户端连接中止导致分布式事务失败例子,
        如果分支事务执行到prepare状态时,数据库异常,且不能正常启动,需要使用备份和binlog来恢复数据,那么那些在prepare状态的分支事务因为并没有记录到binlog
所以不能通过binlog进行恢复,在数据库恢复后,将丢失这部分数据。
        mySql的分布式事务还存在较严重的缺陷,数据库或者应用异常的情况下,可能导致分布式事务的不完整。如果应用对事务完整性要求不高,可以考虑使用
原创粉丝点击