【MySQL】事务

事务

事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

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

基本操作:

  • 查看事务提交方式
    SELECT @@AUTOCOMMIT;
  • 设置事务提交方式,1为自动提交,0为手动提交,该设置只对当前会话有效
    SET @@AUTOCOMMIT = 0;
  • 提交事务
    COMMIT;
  • 回滚事务
    ROLLBACK;
-- 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 = '李四';


set @@autocommit = 0;
-- 设置手动提交后上面代码改为:
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
commit;

操作方式二:

开启事务:
START TRANSACTION 或 BEGIN TRANSACTION;
提交事务:
COMMIT;
回滚事务:
ROLLBACK;

操作实例:

start transaction;
select * from account where name = '张三';
update account set money = money - 1000 where name = '张三';
update account set money = money + 1000 where name = '李四';
commit;

四大特性ACID

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

并发事务

问题 描述
脏读 一个事务读到另一个事务还没提交的数据
不可重复读 一个事务先后读取同一条记录,但两次读取的数据不同
幻读 一个事务按照条件查询数据时,没有对应的数据行,但是再插入数据时,又发现这行数据已经存在

关于不可重复读和幻读的区别通俗解释

  1. 幻读(Phantom Read):
  • 想象一下你在超市购物。当你拿着购物篮走到某个货架前,发现了一些商品。
  • 突然,另一个顾客拿走了一些商品,然后你又回头看,发现有更多的商品出现在货架上,就好像它们是幻影一样。
  • 在数据库中,这就是幻读。当一个事务在读取一组数据时,另一个事务插入或删除了一些数据,导致第一个事务看到了之前不存在的数据(幻影数据)。
  1. 不可重复读(Non-repeatable Read):
  • 想象一下你在图书馆借一本书,然后回家阅读。不久后,你又回到图书馆,但发现书已经被另一个人借走了。
  • 在数据库中,这就是不可重复读。当一个事务在读取一条数据后,另一个事务修改或删除了该数据,导致第一个事务再次读取时,发现数据已经改变,无法重复读取相同的内容。

区别:

  • 幻读主要涉及到新增或删除数据,即数据的数量发生变化。事务A在读取一组数据时,事务B插入或删除了一些数据,导致事务A看到了幻影数据。
  • 不可重复读主要涉及到已有数据的修改。事务A在读取数据后,事务B修改了这些数据,导致事务A再次读取时,发现数据已经不同。

总之,幻读和不可重复读都是多个事务并发访问数据库时可能出现的问题,但它们关注的方面不同。幻读关注新增或删除数据的情况,而不可重复读关注已有数据的修改情况。不同的事务隔离级别可以控制这些问题的发生,以满足应用程序的需求。

并发事务隔离级别:

隔离级别 脏读 不可重复读 幻读
Read uncommitted
Read committed ×
Repeatable Read(默认) × ×
Serializable × × ×
  • √表示在当前隔离级别下该问题会出现
  • Serializable 性能最低;Read uncommitted 性能最高,数据安全性最差

查看事务隔离级别:
SELECT @@TRANSACTION_ISOLATION;
设置事务隔离级别:
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
SESSION 是会话级别,表示只针对当前会话有效,GLOBAL 表示对所有会话有效

关于隔离级别的详细演示,看完之后会有更直观的理解:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=55&vd_source=78c306a3add9ef0e735c2d51eb5d0877

你可能感兴趣的:(数据库,mysql,数据库,sql)