当前位置:   article > 正文

【第四篇】MySQL事务详解【重点】_mysql begin commit

mysql begin commit

1.1 事务简介

MySQL数据库事务:事务是一组SQL语句组成的逻辑处理单元,这些操作要么全做要么全不做,是一个不可分割的工作单位

MySQL中只有innodb引擎才能支持事务处理

数据库默认事务时自动提交的,也就是发一条SQL它就执行一条。如果想多条SQL放在一个事务中执行,则需要使用事务进行处理。当我们开启事务,并且没有提交,MySQL会自动回滚事务,或者我们使用rollback命令手动回滚事务。

事务(Transaction):一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务

一个完整的业务需要批量DML(数据操纵语言 insert、update、delete) 语句共同联合完成

事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

1.2 事务的四大特性(ACID)

  • Automicity:原子性,事务是最小的执行单位,不允许分割。
  • Consistency:一致性,数据库从一个正确的状态变化到另一个正确的状态;
  • Isolation:隔离性,并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的
  • Durability:持久性,一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

1.3 事务提交与回滚

mysql默认情况下,事务是自动提交的,也就是说只要执行了一条DML语句就开启了事务,并且提交了事务

自动提交机制是可以关闭的
在这里插入图片描述
开启事务
在这里插入图片描述
回滚事务
在这里插入图片描述

1.4 事务产生的问题和事务的隔离界别

事务同时执行出现的问题

脏读: 事务A读取了B更新的数据,然后B回滚事务A读取到的就是脏数据
不可重复读: 事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致前后结果不一致。
幻读: A管理员将学生按照分数分为ABCDE,B管理员在A操作完全部数据之后发现有一条记录没操作,好像出现幻觉一样。
总结: 不可重复读侧重修改,幻读侧重新增和删除。不可重复读要锁符合条件的行数据,幻读要锁表

事务的隔离级别

读未提交: 一个事务还没提交时,它做的变更就能被别的事务看到。
读已提交(Orlace默认级别): 一个事务提交之后,它做的变更才会被其他事务看到。解决脏读。
可重复读(mysql默认级别): 事务不会读到其它事务提交的修改(一开始读到什么,最后也读到什么)解决脏读、不可重复读
串行化: 解决了脏读、不可重复读、幻读,相当于单进程,效率低下。

1.5 事物的作用范围

事务隔离级别作用范围有2种:

全局级别(global):对所有会话有效
会话级别(session):只对当前会话有效

1.6 设置事务隔离级别

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>
GLOBAL:代表设置全局事务级别
SESSION:代表设置会话事务级别

isolation-level:可以是
- READ UNCOMMITTED
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE

设置会话隔离级别为READ COMMITTEDSET TRANSACTION ISOLATION LEVEL READ COMMITTED;SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;


设置全局隔离级别为READ COMMITTEDSET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

1.7 查看事务隔离级别

查看会话隔离级别

select @@tx_isolation;
show variables like '%isolation%';


查看全局隔离级别
select @@global.tx_isolation;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.8 redis事务和mysql事务的区别

1.8.1 事务指令

Mysql:begin、commit、rollback

Redis:multi(标记事务开始)、exec(执行commands队列)、discard(结束事务,并消除commands队列)

1.8.2 事务底层实现

Mysql基于undo日志和redo日志

undo日志实现了rollback操作
redo日志实现了commit操作

Redis基于Commands队列实现

1.8.3 事务默认状态

Mysql默认开启

无论是否开启事务,都会马上执行命令,只是开启事务后将状态存入redo日志,commit后才写入磁盘

Redis默认关闭

没开启事务:立即执行并返回结果,直接写入内存
开启事务:不会立刻执行,排入队列,并返回队列状态,调用exec才会执行commands中的命令

1.8.4 事务是否支持回滚

Mysql支持回滚
Redis不支持回滚,可以使用WATCH去监听key在事务发生之前是否被修改,若被修改则回滚

WATCH
在这里插入图片描述
UNWATCh(取消所有监视)
在这里插入图片描述

1.8.5 事务是否原子性

mysql事务是原子性的,关系型数据库中的事务都是原子性的
在这里插入图片描述
redis命令是原子性的,事务不是原子性的

若事务队列中存在命令错误(类似java编译性错误),执行exec,所有命令都不会执行
若事务中存在语法错误(类似java 1/0的运行时异常),执行 exec,正确命令会被执行,错误命令抛出异常
演示1
在这里插入图片描述
演示2
在这里插入图片描述

1.9 Spring事务的七大传播属性

在这里插入图片描述

PROPAGATION_REQUIRED: 如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

PROPAGATION_SUPPORTS: 支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘

PROPAGATION_MANDATORY: 支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

PROPAGATION_REQUIRES_NEW: 创建新事务,无论当前存不存在事务,都创建新事务。

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

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

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

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

闽ICP备14008679号