• mysql 开发基础系列21 事务控制和锁定语句(下)


    1.  隐含的执行unlock tables

      如果在锁表期间,用start transaction命令来开始一个新事务,会造成一个隐含的unlock tables 被执行,如下所示:

    会话1

    会话2

    SELECT * FROM country WHERE country='德国';

    记录为空

    SELECT * FROM country WHERE country='德国';

    记录为空

    --  对country表进行加 写锁

    LOCK TABLE country WRITE;

    -- 查询 整个表读取被阻塞

    SELECT * FROM country WHERE country='德国';

    -- 插入一条记录

    INSERT INTO country(country, last_update) VALUES('德国',NOW());

    共 1 行受到影响

    country_id        country    last_update

    2       中国         2018-07-03 18:06:45

    7       德国         2018-07-12 17:22:08

    查询等待

    -- 开始一个新事务

    START TRANSACTION;

    会话1开始一个新事务时,表锁被释放,可以查询:

    SELECT * FROM country;

    country_id        country    last_update

    2       中国         2018-07-03 18:06:45

    7       德国         2018-07-12 17:22:08

       在同一个事务中,最好不要操作不同存储引擎的表, 因为commit 和rollback 只能对事务类型的表进行提交和回滚。通常提交的事务会记录到二进制日志中, 但如果一个事务中包含非事务类型的表,那么回滚操作也会被记录到二进制日志中,以确保非事务类型表的更新可以被复制到从slave数据库中。

    2.  savepoint

      在事务中可以通过定义 savepoint,指定回滚事务的一个部分,但是不能提交事务的一个部分, 对于复杂的应用,可以定义多个不同的savepoint 来适应不同的条件,回滚不同的savepoint。如果定义了相同名字的savepoint,则后面定义的savepoint会覆盖之前的定义。对于不再需要使用的savepoint,可以通过release savepoint 来删除savepoint。
      下面举例回滚事务的一个部分,通过定义savepoint来指定需要回滚的事务的位置。

    会话1

    会话2

    SELECT * FROM country WHERE country='德国';

    结果为空

    SELECT * FROM country WHERE country='德国';

    结果为空

    -- 启动一个事务 插入一条记录

    START TRANSACTION ;

    INSERT INTO country(country, last_update) VALUES('德国',NOW());

    -- 可以查询到刚插入的记录

    SELECT * FROM country WHERE country='德国';

    country_id        country    last_update

    12           德国         2018-07-12 18:17:12

    SELECT * FROM country WHERE country='德国';

    结果为空

    --  定义savepoint 名为testsavepoint

    SAVEPOINT savepoint_test;

    -- 继续插入一条记录, 此时事务还会提交

    INSERT INTO country(country, last_update) VALUES('日本',NOW());

    SELECT * FROM country WHERE country='德国' or country='日本'

    结果为空

    SELECT * FROM country WHERE country='德国' or country='日本'

    country_id        country    last_update

    12           德国         2018-07-12 18:17:12

    13           日本         2018-07-12 18:20:33

    -- 回滚刚才的定义

    ROLLBACK TO SAVEPOINT savepoint_test;

    SELECT * FROM country WHERE country='德国' OR country='日本'

    country_id        country    last_update

    12         德国         2018-07-12 18:17:12

    SELECT * FROM country WHERE country='德国' or country='日本'

    结果为空

    -- 提交事务

    COMMIT;

    SELECT * FROM country WHERE country='德国' OR country='日本'

    country_id        country    last_update

    12           德国         2018-07-12 18:17:12

    SELECT * FROM country WHERE country='德国' OR country='日本'

    country_id        country    last_update

    12           德国         2018-07-12 18:17:12

  • 相关阅读:
    编译安装linux内核步骤
    怎样在github上协同开发
    在JSP里使用CKEditor和CKFinder
    tomcat结合nginx使用小结
    JAVA学习笔记——(五)
    JAVA学习笔记——(四)
    JAVA学习笔记——(三)
    JAVA学习笔记——(二)
    JAVA学习笔记——(一)
    ansible
  • 原文地址:https://www.cnblogs.com/MrHSR/p/9305018.html
Copyright © 2020-2023  润新知