美文网首页
mysql事务

mysql事务

作者: 梁帆 | 来源:发表于2021-12-14 22:45 被阅读0次

    mysql的InnoDB引擎支持事务,它用COMMIT、SAVEPOINT及ROLLBACK支持事务处理。
    事务就是一个原子性操作,一个完整的业务逻辑。
    事务的特点是四点,简称ACID。原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

    一、事务的情景举例

    试想一下下面的情景:
    A向B转了100元,那么

    A的账户-100
    B的账户+100

    这就是一个完整的业务逻辑。对于在mysql中就是两个update语句,它们要么同时成功,要么同时失败,是不可再分的。

    二、事务是DML语句专有的

    只有DML语句才有事务这么一说,其它语句与事务无关。
    DML语句指的是数据操纵语句,包括update、insert、delete;而DDL语句指的是数据定义语句,包括创建数据库中的各种对象——表、视图、索引、同义词、聚簇等。
    只要你的操作涉及到数据的增删改,那就意味着一定要考虑安全问题。

    三、事务的开始和结束

    InnoDB存储引擎中,提供了一组用于记录事务性活动的日志文件。当事务的执行过程中,每一条DML语句都会记录到这个日志文件里。如果COMMIT提交的话,日志文件就会被清空。

    • 开启事务:start transaction;
    • 提交事务:commit;
    • 回滚事务:rollback;

    有案例如下:
    在初始状态下,某张表中没有任何rows的。

    // 1.开始事务
    start transaction;
    // 2.写DML语句
    insert ...
    insert ...
    

    这里我们如果进行select语句查看表中数据时,会发现表中已经存有了数据;此时如果选择执行

    // 3.回滚事务
    rollback;
    

    再次查询表中数据,会发现数据已经没了。
    如果你执行

    // 3.提交事务
    commit;
    

    在已经提交了的情况下,你再使用rollback,也无法使得数据还原到事务前的状态。

    注意,在没有start transaction的情况下,你直接输入DML语句,就相当于是被commit了的事务,只不过它是被默认执行的;此时你执行rollback不会有任何用。

    这种自动提交实际上是不符合我们的开发习惯的,因为一个业务通常是需要多条DML语句执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。

    四、事务的隔离级别

    重点说下事务的隔离性(isolation)
    事务和事务之间的隔离级别主要有4个级别。

    • 1.读未提交:read uncommitted,事务A可以读到事务B未提交的数据。存在的问题是脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。这种隔离级别基本没有数据库会用。
    • 2.读已提交:read committed,事务A可以读到事务B已提交的数据。这种隔离级别解决了脏读的现象。存在的问题是不可重复读取数据:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。这也是oracle数据库的默认隔离级别。
    • 3.可重复读:repeatable read,事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变。它存在的问题是可能会出现幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。这是mysql的默认隔离级别。
    • 4.序列化(串行化):serializable,所有的事务都是串行处理的,这样牺牲了效率。

    隔离级别以此从低到高。

    相关文章

      网友评论

          本文标题:mysql事务

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