博客
关于我
MySQL学习-MySQL数据库事务
阅读量:788 次
发布时间:2023-02-12

本文共 2373 字,大约阅读时间需要 7 分钟。

MySQL数据库事务

1. 什么是事务?

一个事务是一个完整的业务逻辑单元,不可再分。例如:银行账户转账,从A账户向B账户转账10000元,需要执行两条UPDATE语句:

update t_act set balance = balance - 10000 where actno = 'act-001';update t_act set balance = balance + 10000 where actno = 'act-002';

以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功、一条失败。

要想保证以上两条DML语句同时成功或者同时失败,就需要使用数据库的“事务机制”。


2. 与事务相关的语句只有:DML语句(insert、delete、update)

为什么?

因为它们这三个语句都是和数据库表当中的“数据”相关的。

事务的存在是为了保证数据的完整性、安全性。


3. 假设所有的业务都能用1条DML语句搞定,还需要事务机制吗?

不需要事务机制。

但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。


2. 事务的原理

假设一个事儿,需要先执行一条INSERT,接着执行一条UPDATE,最后执行一条DELETE,这个事儿才算完成。

开启事务机制:

  • 执行INSERT语句
  • 执行UPDATE语句
  • 执行DELETE语句

这些操作都会记录到数据库的操作历史中,但不会真正修改硬盘上的数据。

提交事务或回滚事务(结束):

  • 提交语句用commit
  • 回滚事务用rollback

TCL(事务控制语言)可以设置一个保存点,让其回滚到某个地方。


3. 事务的特性

事务包括四大特性:ACID

  • A: 原子性:事务是最小的工作单元,不可再分。
  • C: 一致性:事务必须保证多条DML语句同时成功或者同时失败。
  • I: 隔离性:事务A与事务B之间具有隔离。
  • D: 持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。

4. 事务的隔离性(重点)

事务隔离性存在隔离级别,理论上隔离级别包括4个:

  • 读未提交(read uncommitted)

    • 对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。
    • 存在脏读(Dirty Read)现象:表示读到了脏的数据。
    • 数据不稳定,还有持久性,断电就没有了,也有可能会回滚。
  • 读已提交(read committed)(默认)

    • 对方事务提交之后的数据我方可以读取到。
    • 解决了脏读现象。
    • 存在的问题是:不可重复读。
  • 可重复读(repeatable read)

    • 解决了不可重复读问题。
    • 存在的问题是:读取到的数据是幻象。
  • 序列化读/串行化读(serializable)

    • 解决了所有问题。
    • 效率低,需要事务排队。
  • MySQL数据库默认隔离级别是:可重复读。


    5. 演示事务

    5.1 演示概述

    MySQL事务默认情况下是自动提交的。只要执行任意一条DML语句,则提交一次。

    怎么关闭自动提交?

    start transaction;

    5.2 演示读未提交

    设置事务的全局隔离级别:

    set global transaction isolation level read uncommitted;

    查看事务的全局隔离级别:

    select @@global.tx_isolation;
    • 事务1

      mysql> start transaction;mysql> select * from t_user;

      在这之间事务2插入了一条数据smith。

    • 事务2

      mysql> start transaction;mysql> insert into t_user(username) values("SMITH");
    • 结果

      • 事务1读到了未提交的数据,读到了SMITH。

    5.3 演示读已提交

    设置事务隔离级别为读已提交:

    set global transaction isolation level read committed;
    • 事务1

      mysql> start transaction;mysql> select * from t_user;

      在这之间事务2插入了一条数据。

    • 事务2

      mysql> start transaction;mysql> insert into t_user(username) values("test");mysql> commit;
    • 结果

      • 事务1读到了提交的数据,读不到未提交的数据。

    5.4 演示可重复读

    设置事务隔离级别为可重复读:

    set global transaction isolation level repeatable read;
    • 事务1

      mysql> select * from t_user;

      在这之间事务2对数据进行了无数次修改并进行了提交。

    • 事务2

      mysql> select * from t_user;
    • 结果

      • 读到的数据是幻象,和数据库中的实际数据不一致。

    5.5 演示串行化读

    设置事务隔离级别为串行化读:

    set global transaction isolation level serializable;
    • 事务1

      mysql> start transaction;mysql> select * from t_user;mysql> insert into t_user(username) values('hehe');

      此时,事务1还未提交。

    • 事务2

      mysql> start transaction;mysql> select * from t_user;
    • 结果

      • 事务2卡住了,直到事务1提交。

    通过这些演示可以看出,事务的隔离级别直接影响到事务的安全性和效率。

    转载地址:http://arbfk.baihongyu.com/

    你可能感兴趣的文章
    mysql主从同步配置方法和原理
    查看>>
    mysql主从复制 master和slave配置的参数大全
    查看>>
    MySQL主从复制几个重要的启动选项
    查看>>
    MySQL主从复制及排错
    查看>>
    mysql主从复制及故障修复
    查看>>
    MySQL主从复制的原理和实践操作
    查看>>
    mysql主从复制,读写分离,半同步复制实现
    查看>>
    MySQL主从失败 错误Got fatal error 1236解决方法
    查看>>
    MySQL主从架构与读写分离实战
    查看>>
    MySQL主从篇:死磕主从复制中数据同步原理与优化
    查看>>
    mysql主从配置
    查看>>
    MySQL之2003-Can‘t connect to MySQL server on ‘localhost‘(10038)的解决办法
    查看>>
    MySQL之CRUD
    查看>>
    MySQL之DML
    查看>>
    Mysql之IN 和 Exists 用法
    查看>>
    MYSQL之REPLACE INTO和INSERT … ON DUPLICATE KEY UPDATE用法
    查看>>
    MySQL之SQL语句优化步骤
    查看>>
    MYSQL之union和order by分析([Err] 1221 - Incorrect usage of UNION and ORDER BY)
    查看>>
    Mysql之主从复制
    查看>>
    MySQL之函数
    查看>>