数据库进阶教学——事务

编程入门 行业动态 更新时间:2024-10-18 12:27:47

数据库<a href=https://www.elefans.com/category/jswz/34/1769503.html style=进阶教学——事务"/>

数据库进阶教学——事务

目录

一、事务简介

二、事务操作方式

1、设置事务提交方式

1.1、命令

1.2、示例

2、开启事务

2.1、命令

2.2、示例

三、事务四大特性

四、并发事务问题

五、事务隔离级别

5.1、命令

5.2、示例

5.2.1、脏读

5.2.2、不可重复读

5.2.3、幻读


一、事务简介

  • 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败
  • 例如,张三要从银行向李四转1000元,银行需要正确操作3个步骤才能完成转账,如果其中某个步骤出错,则会出现异常,那么就可以把这3个步骤当作是一个事务。
    • 在操作前,开启事务,正确完成所有操作后,才提交事务,否则回滚事务。
    • 回滚事务:把之前临时修改的数据,全部恢复。

二、事务操作方式

  •  新建一个用户数据表。
    • create table account(id int auto_increment primary key comment '主键ID',name varchar(10) comment '姓名',money int comment '余额'
      )comment '账户表';
  • 向用户数据表中插入两条用户数据。
    • insert into account(id, name, money) VALUES (null,'张三',2000),(null,'李四',2000);

1、设置事务提交方式

1.1、命令
  • MySQL的事务提交方式默认是自动的,可以设置为手动提交方式。
    • # 查看事务的提交方式,1为自动,0为手动。
      SELECT @@autocommit ;
      # 设置事务提交方式为手动0
      SET @@autocommit = 0;
  • 提交事务
    • COMMIT;
  • 回滚事务
    • ROLLBACK;
1.2、示例
  • 查看事务提交的方式。
  • 此时为自动提交,将其修改为手动提交。
  • 转账操作总共为三步。
    • # 1、查询张三账户余额
      select * from account where name = '张三';
      # 2、将张三账户余额-1000
      update account set money = money - 1000 where name = '张三';
      # 3、将李四账户余额+1000
      update account set money = money + 1000 where name = '李四';
  •  依次输入上面三条命令执行。
  • 刷新用户表,发现张三和李四的余额并没有任何变化,因为此时事务提交方式已经改为了手动。需要另外执行指令才能完成操作。
  • 提交事务,转账成功。
  • 假设一个操作出错的情况。
    • 在执行第三条操作的时候,报错了,此时就不能将这个事务进行提交,不然会出错。
  • 回滚事务,张三和李四的余额并没有任何变化。

2、开启事务

2.1、命令
  • 开启事务
    • START TRANSACTION;
      或
      BEGIN;
  • 提交事务
    • COMMIT;
  • 回滚事务
    • ROLLBACK;
2.2、示例
  • 先把事务提交方式修改回自动提交。
  • 直接测试异常情况,开启事务,执行下列指令。
    • select * from account where name = '张三';
      update account set money = money - 1000 where name = '张三';
      操作出错。。。
      update account set money = money + 1000 where name = '李四';
    • 此时发生异常,但表中的数据并未发生变化。执行回滚即可恢复。

三、事务四大特性

  • 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(lsolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
  • 持久性(Durabilitv):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

四、并发事务问题

  • 两个事务同时操作数据库时所引发的一些问题。
  • 脏读:一个事务读到另外一个事务还没有提交的数据。
  • 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
  • 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”。

五、事务隔离级别

隔离级别脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable Read(默认)××
Serializable×××
  • 【注】事务隔离级别越高,数据越安全,但是性能越低

5.1、命令

  • 查看事务隔离级别
    • SELECT @@TRANSACTION_ISOLATION;
  • 设置事务隔离级别
    • SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 
      # session 只针对当前对话端有效
      # global 针对所有对话端有效

5.2、示例

  • 打开两个终端,模拟两个事务同时对数据库进行操作。
5.2.1、脏读
  • 将其中一个终端的事务隔离级别设置为Read uncommitted。
  • 模拟读取脏数据的情况。
    • 此时,左侧第二次读取的数据为脏数据,因为右侧终端的事务并未提交。
  • Read committed可以解决脏读的问题。先将两个终端都rollback。
  • 将其中一个终端的事务隔离级别设置为Read committed。
  • 模拟读取脏数据的情况。
    • 此时,左侧第二次读取的数据并未发生改变。
  • 将右侧终端的事务提交,左侧读取的数据才发生改变。
5.2.2、不可重复读
  • 此时事务隔离级别为Read committed,继续使用两个终端进行下列操作(之前的事务开启了记得关闭)。

    • 左侧两次读取的数据不相同,这就是不可重复读问题。
  • Repeatable Read可以解决不可重复读问题,先将左侧终端commit。
  • 将左侧终端的事务隔离级别设置为Repeatable Read。
  • 重新模拟不可重复读的情况。
    • 此时左侧两次读取的数据相同。
  • 将左侧事务提交后,再次查询才看到数据被修改了。
5.2.3、幻读
  • 此时事务隔离级别为Repeatable Read,继续使用两个终端进行下列操作。
    • 左侧先查询id=3的用户,发现该用户不存在;右侧此时插入id=3的用户,并且提交了事务;左侧此时因为没有查询到id=3的用户而要插入id=3的用户,但发现id=3的用户已经存在。再次查询发现,id=3的用户依旧不存在。此时就出现了幻读的问题。
  • Serializable(串行化)可以解决幻读问题,先将左侧终端commit。
  • 将左侧终端的事务隔离级别设置为Serializable。
  • 重新模拟幻读的情况。
    • 左侧查询发现没有id=4的用户后,右侧想要执行插入操作却并未成功,而是需要等待左侧事务提交后才能进行操作。

更多推荐

数据库进阶教学——事务

本文发布于:2023-11-17 14:00:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1642680.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:进阶   事务   数据库

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!