当前位置:   article > 正文

MySQL--事务详述

MySQL--事务详述

1. 事务简介

事务是一组操作的集合, 它是一个不可分割的工作单位, 事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求, 即这些操作要么同时执行成功, 要么同时执行失败.  

默认MySQL的事务是自动提交的, 也就是说, 当执行一行DML语句, MySQL会立即隐式的提交事务. 

例如: 一组操作: 张三给李四, 转了1000元.

逻辑单元: 逻辑单元1: 张三账户余额 - 1000元                

                逻辑单元2: 李四账户余额 + 1000元

  1. *
  2. 事务详解:
  3. 例如: 一组操作: 张三给李四, 转了1000元.
  4. 逻辑单元: 逻辑单元1: 张三账户余额 - 1000
  5. 逻辑单元2: 李四账户余额 + 1000
  6. */
  7. -- 1.创建表
  8. # 1.1 创建account表
  9. create table account(
  10. id int primary key auto_increment,
  11. name varchar(10) not null ,
  12. money int not null
  13. );
  14. # 1.2 向表中插入数据
  15. insert into account values (null, '张三', 2000),(null, '李四', 2000);
  16. # 1.3 查询数据
  17. select * from account;
  18. # 1.4 恢复到初始金额(张三李四账户金融各2000元)
  19. update account set money = 2000 where name in('张三', '李四');

查询结果: 

2. 事务操作

2.1 程序异常: 当程序出现异常时, 异常后的事务将不会被执行.

例如:

  1. # (转账操作)
  2. -- 2.对于当前来说, 每一条SQL都是一个事务,
  3. # 2.1 查询张三账户余额
  4. select * from account where name = '张三';
  5. # 2.2将张三账户余额 - 1000
  6. update account set money = money-1000 where name = '张三';
  7. 程序输出异常...
  8. # 此处设置程序输出异常, 则程序执行失败,张三的余额为1000元, 但是李四余额还是2000元.
  9. # 为了解决这种程序异常的问题,我们就需要将张三和李四的转账操作放置在一个 事务中执行.
  10. # 2.3 将李四的账户余额+1000
  11. update account set money = money + 1000 where name = '李四';

执行结果: 

2.2 事务的操作与两种方式

为了解决程序异常的, 我们需要将该程序相关的事务封装到一个事务中执行.

方式一: 通过关闭事务的自动提交, 通过commit去提交, 通过rollback去回滚事务.

格式:

  • 查看/设置事务的提交方式:
    select @@autocommit;   # 1 是自动提交
    set @@autocommit = 1;  # 0 是手动提交
  • 提交事务:
    commit;
  • 回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态):
    rollback ;
    
  1. -- 3. 将MySQL中的自动提交设置为手动提交
  2. -- 查看/设置事务的提交方式 (注意: 此处设置的是会话参数, 只针对当前窗口有效)
  3. select @@autocommit; # 1 是自动提交
  4. set @@autocommit = 1; # 0 是手动提交
  5. # 3.1 查询张三账户余额
  6. select * from account where name = '张三';
  7. # 3.2将张三账户余额 - 1000
  8. update account set money = money-1000 where name = '张三';
  9. # 3.3 将李四的账户余额+1000
  10. update account set money = money + 1000 where name = '李四';
  11. -- 提交事务:
  12. commit;
  13. -- 回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态)
  14. rollback ;

方式二: 可以通过指令来开启事务, 通过commit去提交, 通过rollback去回滚事务.

格式:

  • 开启事务 
    有两种命令: start transaction 或 begin
  • 提交事务:
    commit;
  • 回滚事务:
  • rollback ;
  1. -- 4. 方式二: 将MySQL中的自动提交设置为手动提交
  2. # 开启事务 (有两种命令: start transaction 或 begin)
  3. start transaction ;
  4. # 4.1 查询张三账户余额
  5. select * from account where name = '张三';
  6. # 4.2将张三账户余额 - 1000
  7. update account set money = money-1000 where name = '张三';
  8. # 4.3 将李四的账户余额+1000
  9. update account set money = money + 1000 where name = '李四';
  10. # 提交事务:
  11. commit;
  12. # 回滚事务(当事务执行过程中出现异常时, 可以回滚事务, 回到执行前的状态)
  13. rollback ;

3. 事务四大特征--ACID

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

4. 并发事务问题

就是A事务和B事务同时操作一张数据表而引发的问题, 

        1) 脏读: 

一个事务读到另外一个事务还没有提交的数据

        2) 不可重复读:

一个事务先后读取同一条记录, 但两次读取的数据不同, 称之为不可重复度.

        3) 幻读:

一个事务按照条件查询数据时, 没有对应的数据行, 但是在插入数据时, 有发现这样数据已经存在, 好像出现了''幻影'.'

5. 事务隔离级别

提示: 就是解决事务并发所引发的问题

5.1事务隔离级别
隔离级别脏读不可重复读幻读
Read uncommitted

Read committed

(Oracle默认)

×

Repeatable Read

(MySQL默认)

××
Serializable×××

5.2 常用操作
1) 查看事务隔离级别:
select @@transaction_isolation;
2) 设置事务隔离级别

  1. # 设置当前会话窗口的事务隔离级别
  2. set session transaction isolation level {Read uncommitted | Read committed | Repeatable Read | Serializable}
  3. # 设置全局的事务隔离级别
  4. set global transaction isolation level {Read uncommitted | Read committed | Repeatable Read | Serializable}
5.3 事务隔离级别图解:
  • 在 Read uncommitted级别下,会出现脏读情况: 

事务B更新没有提交, 但是事务A却读到了数据, 此时读取的就脏数据.

  • 在 Read committed 解决了脏读问题:

  •  在 Read committed 出现了不可重复读的问题:

  •   在 Repeatable Read 解决不可重复读的问题:

  •   在 Repeatable Read 出现了幻读的问题: 

 

  •  在 Serializable 解决了幻读的问题: 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/613372
推荐阅读
相关标签
  

闽ICP备14008679号