MYSQL事务(原子性,一致性,隔离性,持久性)

事务的简介

事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
默认MySQL的事务是自动提交的,也就是说,当执行一条增删改查语句时,MySQL会立即隐式的提交事务,事务也可以我们手动开启事务,回滚事务和提交事务。
每一次sql都是一个事务,运行完成,自动提交事务。

事务的操作

查看/设置事务提交方式,1是默认提交,0是手动提交,
SELECT @@AUTOCOMMIT  
SET @@AUTOCOMMIT=0 
----------------------------
开启事务
START TRANSACTION 或者 BEGIN;
----------------------------
提交事务
COMMIT;
----------------------------
回滚事务
ROLLBACK;

事务的四的特性

原子性:事务是不可分割的最小单元,要么全部成功,要么全部失败。
一致性: 事务完成时,必须使所有的数据保持一致的状态。
隔离性: 数据库系统提供了隔离机制,保证事务在不受外部并发操作影响的独立环境下运行,多个事务,不会相互影响,他们都是在单独的一个空间进行运行。
持久性: 事务一旦提交或回滚,他对数据中的数据的改变是永久的。事务一旦提交或回滚就会永久保证在磁盘里。

并发事务问题

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

事务隔离级别

√表示在当前隔离级别下该问题会出现

隔离级别脏读不可重复读幻读
Read uncommitted
Read committed×
Repeatable Read(默认)××
Serializable×××

Read uncommitted:

  • 读未提交,最低的隔离级别,可能造成脏读、不可重复读、幻读。
  • 所以一般情况下,该隔离级别在实际应用中很少使用。

Read committed(oracle默认):

  • 读已提交,可以避免脏读,但是可能造成不可重复、幻读。
  • 两个事务并发执行,事务a第一次查询是1, 事务b随后将1更新成了2并提交了该事务,事务a第二次查询是2 。
  • 事务和事务之间,更新数据表(删除,添加,修改)并提交事务,其他事务读取的都是你提交后的数据,隔离性比较差。
  • 一个事务所做修改在最终提交以前,对其他事务是不可见的。换句话说,一旦提交,该事务所作的修改对其他正在进行中的事务就是可见的。
  • 这是大多数数据库系统的默认事务隔离级别(例如 Oracle、SQL Server),但不是 MySQL 默认的。
  • 使用可重复读隔离级别可以解决实例中产生的不可重复读问题。

Repeatable Read(MySQL默认):

  • 可重复读,可以避免脏读和不可重复读,但是可能造成幻读。
  • 两个事务并发执行,事务a第一次查询是1, 事务b随后将1更新成了2并提交了该事务,事务a第二次查询是还是1
  • 事务和事务之间,更新数据并提交事务,并不影响我读取数据,事务和事务之间是隔离的,但是会出现幻读的情况,如:事务a第一次查询是三条数据,事务b随后又提交一条id为4的数据并提交了该事务,事务a第二次查询是还三条,后续想添加id为4的数据时发现已经有该数据了。
  • 可重复读解决了部分不可重复读的问题:同一个事务中多次读取同样记录结果是一致的。记录指具体的数据行。

Serializable:

  • 串行化,进行并发事务的时候,只允许一个事务进行操作,操作完成,后面的操作才能继续操作。
  • 最高的隔离级别,完全服从ACID的隔离级别,所以的事务依次执行,可以避免脏读、不可重复读、幻读。
  • 但是该事务隔离级别执行效率低下,且性能开销也最大,所以一般情况下不推荐使用。

从上往下隔离级别越高。
事务隔离基本越高,数据越安全,但是性能差。
Serializable 性能最低,隔离级别高;
Read uncommitted性能最高,数据安全性最差, 一般情况下不会更改事务隔离级别。
不可重复读侧重于修改,幻读侧重于新增或删除。
MySQL InnoDB存储引擎的可重复读并不能避免幻读,需要应用使用加锁读来保证,这加锁读使用到的机制就是Next-Key Locks。
因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是读取已提交(READCOMMITTED),InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读) 并不会有任何性能损失。
InnoDB存储引擎在分布式事务的情况下一般会用到可串行化隔离级别。

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

文章参考:哔哩哔哩动画 bilibili.com 博主:黑马程序员。
如果想转发和使用请加上作者和网址,谢谢!
如果发现文章有问题请指出,谢谢!
后续会继续更新,阅读请关注小昵称。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值