美文网首页java面试
四、MySQL 事务

四、MySQL 事务

作者: AKyS佐毅 | 来源:发表于2018-03-20 17:19 被阅读146次

    1、 数据库事务的概念

    • 在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。
    • 为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
    • 事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。

    2、事务的ACID

      1. 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
      1. 一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
      1. 隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
      1. 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。
    • 数据库的事务由下列语句组成:
      • 一组DML语句,修改的数据在他们中保持一致

      • 一个 DDL (Data Define Language) 语句

      • 一个 DCL (Data Control Language)语句

      • DCL(Grant(赋于权限 ) / Revoke(回收权限 ))

      • 1、开始于第一个执行的语句

      • 2、结束于:

        • 用户执行COMMIT 或 ROLLBACK。
        • 单个的DDL or DCL 语句。
        • 用户连接异常错误,或者用户断开连接 。
        • 系统崩溃。

    3、事务控制语句

    • COMMIT和 ROLLBACK可以显式的控制事务。
    • 好处:
      • 1、保证数据一致性,修改过的数据在没有提交之前是不能被其他用户看到的。
      • 2、在数据永久性生效前重新查看修改的数据
      • 3、将相关操作组织在一起,一个事务中相关的数据改变或者都成功,或者都失败。

    4、事务的隔离级别

    • SQL 中定义了四种隔离级别, 每种级别都规定了一个事务所做的修改,哪些在事务内和事务间是可见的, 哪些是不可见的. 较低的隔离通常可以执行更高的并发, 系统的开销也更低.

    • SQL 标准中的四种隔离有:

      • READ UNCOMMITED(未提交读)
        在 READ UNCOMMITED 级别中, 事务的修改, 即使没有提交, 对其他事务也是可见的. 其他事务可以读取此事务中的未提交的数据, 这也被称为脏读(Dirty Read). 此事务隔离级别会导致很多问题, 并且性能也不会比其他事务隔离级别好多少, 因此在实际环境中很少使用.
      • READ COMMITED(提交读)
        大多数的数据库默认隔离级别都是 READ COMMITED, 但是 MySQL 并不是. 在 READ COMMITED 级别中, 一个事务从开始到提交之前, 所做的任何修改对其他事务都是不可见的.

      这个级别有时候也叫做不可重复读(nonrepeatable read), 因为两次执行相同的查询, 可能会得到不一样的结果.

      • REPEATABLE READ(可重复读),可重复读是 MySQL 的默认事务隔离级别.
        REPEATABLE READ 解决了脏读的问题. 该级别保证了在同一个事务中多次读取同样记录的结果时一致的. 但是理论上, 可重复读隔离级别还是无法解决另一个幻读(Phantom Read)的问题. 所谓幻读, 指的是当某个事务在读取某个范围内的记录时, 另外一个事务又在该范围内插入了新的记录, 当之前的事务再次读取该范围的记录时, 会产生幻行(Phantom Row).

      • SERIALIZABLE(可串行化)
        SERIALIZABLE 是最高的隔离级别. 他通过强制事务串行执行, 避免了前面说的幻读的问题. 简单来说, SERIALIZABLE 会在读取的每一行数据上都加上锁, 所以可能导致大量的超时和锁争用的问题. 实际应用中也很少用到这个隔离级别, 只有在非常需要确保数据的一致性而且可以接受没有并发的情况下, 才考虑采用该级别.

    5、死锁

    • 死锁是指两个或多个事务在同一个资源上相互占用, 并请求锁定对方占用的资源, 从而导致恶性循环的现象. 当多个事务试图以不同顺序锁定资源时, 就可能产生死锁.
    • 死锁发生以后, 只有部分或者完全回滚其中一个事务, 才能打破死锁.

    6、MySQL 中的事务

    • 在 MySQL 提供的众多存储引擎中, 只有 InnoDB 和 NDB Cluster 支持事务.

    • 关于自动提交(AUTOCOMMIT)

      • MySQL 默认采用自动提交(AUTOCOMMIT) 模式. 即如果不显示地开始一个事务, 则每个操作都被当做一个事务执行提交操作.
        我们可以通过 SHOW VARIABLES LIKE 'autocommit';
    • 查询当前是否已经开启了字段提交事务, 例如:

    • 如果是 ON, 则表示已经开启了, 0 或 OFF 表示禁用.
    • 可以通过 set autocommit=0; 来禁用自动提交:

    7、自动提交和非自动提交的区别

    • 下面以一个例子来展示 autocommit 启动和非启动时的区别.首先建立一个测试用的表:
    • 接着关闭自动提交功能: mysql> set autocommit=0;

    • 然后插入一个数据: mysql> INSERT INTO user (id,name,age) VALUES (1, 'xys', 18);

    • 接着查看数据:

    • 数据库中可以查询到这条数据了.

    • 但是我们通过 SHOW BINLOG EVENTS 查看操作日志:

    • 会发现上面的输出中, 并没有插入数据相关的记录, 并且此时如果我们退出 MySQL 的话, 那么我们插入的数据并没有被保存:

    • 如果我们不退出, 而是输入COMMIT; 时, 那么此时数据才真正保存到 MySQL 中:
    • 从上面的操作中我们可以看到, 当禁用了 AUTOCOMMIT 后, 我们对数据库的写入操作并不会实际落地到数据库中, 除非我们显示地提交事务.

    • 接下来, 我们使能 AUTOCOMMIT, 再次进行相同的操作.

    • 然后插入一个数据: mysql> INSERT INTO user (id,name,age) VALUES (1, 'xys', 18);

    • 接着查看数据:

    微信扫码关注java技术栈,每日更新面试题目和答案,并获取Java面试题和架构师相关题目和视频。

    相关文章

      网友评论

        本文标题:四、MySQL 事务

        本文链接:https://www.haomeiwen.com/subject/cbdbqftx.html