• MySQL中的事务


    前言

    本篇文章主要介绍的是事务相关概念,结合MySQL进行分析。

    事务的概念

    事务是用户定义的一个数据库操作序列,是同一情况下下进行的多次对数据库的增删改的行为的集合。可以理解为在同一个流程中多次对数据库进行增删改等操作,我们可以称这些操作是在同一事务中。

    事务的应用场景说明

    在实际的业务开发中,有些业务操作要多次访问数据库。一个业务要发送多条 SQL 语句给数据库执行。需要将多次访问数据库的操作视为一个整体来执行,要么所有的 SQL 语句全部执行成功。如果其中有一条 SQL 语句失败,就进行事务的回滚,所有的 SQL 语句全部执行失败。

    有一个最经典的转账的例子,张三给李四转账,张三账号减钱,李四账号加钱,加钱减钱是在同一事务中。

    -- 创建数据表
    CREATE TABLE account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(10),
    balance DOUBLE
    );
    -- 添加数据
    INSERT INTO account (NAME, balance) VALUES ('张三', 1000), ('李四', 1000);
    

    模拟张三给李四转 500 元钱,一个转账的业务操作最少要执行下面的 2 条语句:

    1. 张三账号-500
    2. 李四账号+500
    -- 1. 张三账号-500
    UPDATE account SET balance = balance - 500 WHERE id=1;
    -- 2. 李四账号+500
    UPDATE account SET balance = balance + 500 WHERE id=2;
    

    假设当张三账号上-500 元,服务器崩溃了。李四的账号并没有+500 元,数据就出现问题了,平白无故少了500元。我们需要保证其中一条 SQL 语句出现问题,整个转账就算失败。只有两条 SQL都成功了转账才算成功。这个时候就需要用到事务。

    MySql提交事务

    MYSQL 中可以有两种方式进行事务的操作:
    1.手动提交事务 2.自动提交事务

    1.MySQL可以使用SQL语句实现手动提交事务

    功能 SQL语句
    开启事务 start transaction;
    提交事务 commit;
    回滚事务 rollback;

    手动提交事务的步骤:
    执行成功的情况:开启事务 -> 执行 SQL 语句 -> 成功 -> 提交事务
    执行失败的情况:开启事务 -> 执行 SQL 语句 -> 失败 -> 回滚事务

    也就是说执行start transaction语句后,执行SQL语句,不会马上生效,而是需要执行commit语句才会生效,执行rollback语句则会取消这一事务内执行过的SQL语句,看起来就好像一个网页中确定或者取消的操作弹框。

    2.mysql中是默认自动提交事务的,也就是说执行一条SQL语句后就会自动提交,立即生效。
    mysql默认自动提交事务是可以修改的,只需要执行SQL语句set autocommit = 0;
    将事务提交方式恢复为自动提交set autocommit = 1;
    这样就不用执行start transaction手动开启事务了。

    事务原理

    事务开启之后, 所有的操作都会临时保存到事务日志中, 事务日志只有在得到 commit 命令才会同步到数据表中,其他任何情况都会清空事务日志(rollback,断开连接等情况)。

    原理图

    步骤:

    1 创建连接时创建此用户临时日志文件
    2 开启事务以后,所有的操作都会先写入到临时日志文件中
    3 所有的查询操作从表中查询,但会经过日志文件加工后才返回
    4 如果事务提交则将日志文件中的数据写到表中,否则清空日志文件。

    回滚点

    在某些成功的操作完成之后,后续的操作有可能成功有可能失败,但是不管成功还是失败,前面操作都已经成功,可以在当前成功的位置设置一个回滚点。可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称之为回滚点。

    回滚点操作语句 SQL语句
    设置回滚点 savepoint 回滚点名字;
    回滚到回滚点 rollback to 回滚点名字;

    总结:设置回滚点可以让我们在失败的时候回到设置的某一回滚点,而不是回到事务开启的时候。

    事务的四大特性(ACID)

    事务特性 含义
    原子性(Atomicity) 事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
    一致性(Consistency) 事务前后数据的完整性必须保持一致
    隔离性(Isolation) 是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离,不能相互影响。
    持久性(Durability) 指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

    事务的隔离级别

    事务在操作时的理想状态:多个事务之间互不影响,如果隔离级别设置不当就可能引发并发访问问题。这些并发问题都是由于不同事务直接交叉了,没有完全隔离开来。

    并发访问的问题 含义
    脏读 一个事务读取到了另一个事务中尚未提交的数据,比如一个事务增加一条数据,但是还没有提交,此时另一个事务读到并使用了这条未提交的数据,这条数据就是脏数据,并不是真实的;因为如果增加这条数据的事务回滚了,那么这条数据就不存在了,但是又被另一个事务读取使用了,就会出问题。删除和更新操作也是一样的
    不可重复读 一个事务中两次读取的数据内容不一致,要求的是一个事务中多次读取时数据是一致的,这是事务 update 时引发的问题 。比如事务A事先读取了数据,事务B紧接了更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
    幻读 一个事务中两次读取的数据的数量不一致,要求在一个事务多次读取的数据的数量是一致的,这是 insert 或 delete 时引发的问题;比如事务A事先读取了数据共100条,事务B紧接着删除或者增加两条数据并提交事务,而事务A再次统计数据时发现数据量不是100条了。

    脏读这种情况是存在的,一个事务未提交的数据,另一个事务是能读到的,只不过在MySQL中默认隔离级别为第二级,屏蔽了这种情况。可以手动设置为读未提交,测试能读到没有提交的数据。

    MySQL数据库有四种隔离级别:上面的级别最低,下面的级别最高。 “是”表示会出现这种问题, “否”表示不
    会出现这种问题。

    级别 名称 隔离级别 脏读 不可重复读 幻读 数据库默认隔离级别
    1 读未提交 read uncommitted
    2 读已提交 read committed Oracle 和 SQL Server
    3 可重复读 repeatable read MySQL
    4 串行化 serializable

    设置事务隔离级别,需要退出 MSQL 再进入 MYSQL 才能看到隔离级别的变化

    CSDN:https://blog.csdn.net/qq_27682773
    简书:https://www.jianshu.com/u/e99381e6886e
    博客园:https://www.cnblogs.com/lixianguo
    个人博客:https://www.lxgblog.com

  • 相关阅读:
    How many things do you really about .net framwork?
    Things that will impact concurrency & capacity behavior of WCF service (with simoultaneous client requests/connections)
    3 ways to do WCF Message Exchange Model
    3 ways to create WCF Client(ChannelFactory)
    Do not apply "using" for the clientWCF Client
    Understanding WCF Session
    Using FaultContract
    3 ways to do WCF Concurrency Management(Single, Multiple, and Reentrant and How to do with Throttling)
    webview使用技巧汇总
    反序列化网易miniblog json格式数据 原创 create by lee
  • 原文地址:https://www.cnblogs.com/lixianguo/p/12522598.html
Copyright © 2020-2023  润新知