MySQL事务

什么是事务?

事务是把一组SQL语句打包为一个整体,这组SQL语句执行过程中要么全部成功,要么全部失败。例如:转账汇款,我们需要的是A转给B1000元,A的账户减少1000元,B的账户增加1000元,而不是单单一个人的变化。如果汇款成功,那么:

1.A的余额减少1000元,B的余额增加1000元。不能单单一个人的变化

2.转账前后两人的总额保持不变。

3.转账后的结果应该存到磁盘中去,以便后续读取

4.转账过程中A和B不能受到其他转账事件的干扰,同一时间段不仅仅是两人之间的转账。

由此引出事务的ACID特性:

1.原子性:支持事务的数据库中最基本的特性,一组SQL要么全都执行成功,要么全不执行,如果执行过程中出现错误,事务就会回滚事务开始状态。

2.一致性:事务执行完成之后,保证数据准确。

3.隔离性:多个事务不能相互影响。

4.持久性:事务一旦提交,就需要保存到存储介质中,无论数据库是否损坏,都不会影响数据的安全。

一致性是通过原子性,隔离性和持久性来实现。

如何理解隔离性?由于MySQL 服务器支持多个客户端同时连接,并且每个客户端连接都可以拥有自己的会话,某次在A,B两个会话读取到甲的余额为1000,在A会话中消费100元,余额900元,B会话消费100元,余额"900元",这样子并不对。这是由于两个会话之间受到了干扰,最终得到的一个错误的结果;此时就要考虑两个会话之间的隔离性,它们之间的操作不能相互影响。正确的是在会话A结果之上执行会话B。在使用数据库的过程中,对于修改只要提交成功,就可以安全的保存,只要回顾就可以恢复事务之初。开启一个事务之后,所写的SQL语句就包含在事务中了,这些SQL语句有ACID特性

如何使用事务?

一些操作

1.开启事务:

2.查看表内容以及修改表数据

3.回滚操作:回滚完成事务结束

4.提交操作

执行完更新操作后,直接commit;事务提交后结束,commit提交之后表明修改生效,以后修改是指此基础上进行的修改。

5.保存点

在事务执行过程中设置保存点,回滚时指定保存点可以将数据恢复到保存点的状态

6.自动/手动提交事务

在平时写sql语句时,默认情况下自动开启提交和回滚的,像之前的增删改,关闭sql之后都是可以打开再次查询到最后一次操作后的情况,当输入错误sql语句报错就是回滚,这时事务只包含一条DML(select,insert,update,delete)语句

6.1 查询当前事务是否自动提交:on表示是,off表示不是

6.2 修改

sql 复制代码
# 重启还是变成自动提交
# 修改配置文件可以设置为自动提交
#设置为自动提交
set autocommit = 1;
set autocommit = on;
#设置手动提交
set autocommit = 0;
set autocommit = off;

注意:使用start transac 或者 begin 开启事务后,必须通过commit,提交才能持久化(或者rollback回滚才能结束),与set autocommit 无关

手动模式下,不用显示开启事务,执行修改操作后,commit 提交以及rollback回滚

已提交的事务不能回滚

三种问题和四种隔离级别

事务之间不同程度的隔离,称为事务的隔离级别,在MySQL的InnoDB引擎中事务的隔离级别四种,安全性从低到高:READ UNCOMMITTED(读未提交),READ COMMITTED(读已提交),REOEATABLE READ(可重复读),SEIALIZABLE(串行化),它们的性能由高到低

READ UNCOMMITTED(读未提交):

允许一个事务读取另一个事务尚未提交 的数据。可能会导致一些问题,包括脏读、不可重复读和幻读等现象。

如果事务A对数据进行了修改,事务B访问了事务A中未提交的数据 ,这种情况叫做**"脏读"** ,如果事务A回滚,导致数据不一致。相关图示:

事务A第一次读取某条数据,由于事务B对此数据进行修改并提交 ,那么下一次事务A读到结果不一致,这种情况叫做**"不可重复读"** 。

图示如下:

一个事务多次执行相同的查询,由于其他事务的插入或者删除,导致查询到的结果集发生变化,这种叫做**"幻读"** 。

READ COMMITTED(读已提交)

一个事务只能读取另一个事务以及提交的数据,解决了脏读的问题。

REOEATABLE READ(可重复读)

一个事务在整个事务期间看到的数据是一致的,表面一个事务内多次读取同一数据,结果始终相同,即时提交了修改,解决了不可重复读的问题。在InnDB引擎中,使用next-key锁,锁住了目标行和之间的间隙,解决了部分的幻读问题

SEIALIZABLE(串行化)

事务完全按照顺序执行,消除所有并发,确保了一个事务在执行过程中不受到其他事务的影响,解决了上述的所有问题。但是并发性差,一个事务开始必须等前一个事务的完成

Next-Key Lock的简单介绍

组成:行锁(Record Lock)以及间隙锁(Gap Lock)。行锁锁定索引记录本身,间隙锁锁定索引记录之间的间隙,以及索引记录之前和索引之后的间隙。

它锁定了一个区间,可以防止其他事务在该区间内插入新的记录,从而避免幻读。比串行化更加的灵活,可以保证数据一致的情况下提高并发性能。

查看和设置隔离级别

全局作用域查看以及当前会话作用域查看隔离级别

两种设置方式:

相关推荐
静听山水7 分钟前
mysql语句执行过程
数据库·mysql
虽千万人 吾往矣25 分钟前
golang gorm
开发语言·数据库·后端·tcp/ip·golang
Q_w77421 小时前
一个真实可用的登录界面!
javascript·mysql·php·html5·网站登录
mariokkm1 小时前
Django一分钟:在Django中怎么存储树形结构的数据,DRF校验递归嵌套模型的替代方案
数据库·django·sqlite
Wang's Blog2 小时前
Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息
数据库·redis
数据龙傲天3 小时前
1688商品API接口:电商数据自动化的新引擎
java·大数据·sql·mysql
engineer-gxd4 小时前
MySQL 表的操作
mysql
cyt涛4 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油4 小时前
01_SQLite
数据库·sqlite