0
点赞
收藏
分享

微信扫一扫

mysql事务详解


概念理解:

举例:

A 支出100 -100
B 收到100 +100

以上操作称作一个事务,是一个不可分割的部分,要么全不做,要么全部做。

事务的特性

一致性:事务前后应该保证状态一致,在这里就是总金额保持一致
原子性:操作要么全部成功要么全部失败
隔离性:用户操作表,数据库为其开启事务,操作过程中不能被其他操作干扰
持久性:事务被修改了就是永久的

脏读 幻读 不可重复读

脏读:事务B查看到事务A未提交的数据
不可重复读:主要在更新 多select 几次发现数据被人update过
幻读:主要在插入 插入发现该数据被人插入过

幻读和不可重复读详解

sql 语句执行的流程

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 将事务日志持久化到 binlog。
  4. 提交事务,在 redo log 中写入commit记录。
  5. 失败回滚记录事务

事务的隔离级别

不可重复读

begin;
SQL1:select value from tab where id = 1; //返回value = 1;
SQL2:select value from tab where id = 1; //返回value = 2;
commit;

因为[SQL1]和[SQL2]执行的中间,别的事务执行了:

begin;
update tab set value = 2 where id = 1;
commit;

而[SQL1]跟[SQL2]执行所拿的Snapshot不一样(RC),造成了不可重复读,而RR隔离级别[SQL1]跟[SQL2]的Snapshot一样,结果也是一样,就不会发生不可重复读的问题。

幻读

begin;
SQL3:select value from tab where id = 1; //表中id=1的记录还没有
SQL4:select value from tab where id = 1;//value=X
commit;

在一个事务中[SQL3]跟[SQL4]读取的数据是有和没有的区别,例如在某些场景下,先检测ID=1的记录是否存在,如果有则跟新,没有就插入。那么在执行[SQL3]的时候,id=1的记录不存在,那么在执行[SQL4]之前,其他事务执行了:

begin;
insert into tab(id,value) values(1,X);
commit;

则[SQL4]就能读取刚才看不见的数据,删除也同理,数据时有时无

事务的传播级别

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

参考文献



举报

相关推荐

0 条评论