什么是事务?
事务是把一组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)。行锁锁定索引记录本身,间隙锁锁定索引记录之间的间隙,以及索引记录之前和索引之后的间隙。
它锁定了一个区间,可以防止其他事务在该区间内插入新的记录,从而避免幻读。比串行化更加的灵活,可以保证数据一致的情况下提高并发性能。
查看和设置隔离级别
全局作用域查看以及当前会话作用域查看隔离级别
两种设置方式: