mysql事务、ACID特性、隔离级别

事务

事务中可能包含一个或多个sql语句,这些语句要么都执行,要么都不执行

测试事务提交
模拟一个银行转账的示例:

create table shop (
`id` int(3) not NULL auto_increment,
`name` varchar(20) not null,
`money` decimal(9,2) not null,
	primary key(`id`)
)engine=INNODB default charset=utf8

insert into account(`name`,`money`) values ('A',2000.00),('B',10000.00)

在这里插入图片描述

-- mysql 是默认开启事务自动提交的
-- set autocommit =0 -- 关闭事务自动提交
-- set autocommit =1	-- (默认开启) 

-- 关闭自动提交
set autocommit =0

-- 事务开启,标记一个事务的开始,从这个之后的sql都在同一个事务内
start transaction 

update shop set `money`=`money`-500 where `name`='A'
update shop set `money`=`money`+500 where `name`='B'

select * from shop

-- 提交:持久化
commit

-- 回滚:数据返回最开始
rollback

-- 事务结束,开启自动提交
set autocommit =1

-- 设置一个事务的保存点
savepoint `保存点名`
-- 回滚到保存点
rollback to savepoint `保存点名` 
-- 撤销保存点 
release savepoint `保存点名`	

在这里插入图片描述
执行第一条后update语句后:
在这里插入图片描述

执行第二条update语句后:

在这里插入图片描述
当回滚事务后再查询:

在这里插入图片描述
当提交事务后,数据持久化:

在这里插入图片描述
事务结束,需要开启自动提交,否则以后操作不会生效

事务操作流程简图:

在这里插入图片描述

事务ACID特性

  • 原子性:事务中的一组操作要么都发生,要么都不发生
    在这里插入图片描述
    原子性表示这两个步骤A转账B收到,要么一起成功,要么一起失败,不能只发生其中一个

  • 一致性:针对一个事务操作前与操作后的状态要保持一致
    在这里插入图片描述
    一致性表示事务操作前800+200=1000状态,事务操作后600+400=1000状态要保持一致

  • 持久性:表示事务结束后的数据不随着外界原因导致数据丢失
    如果事务还没有提交,此时服务器宕机或者断电,重启数据库以后,数据库中的数据应该和之前一样
    如果事务已经提交,服务器宕机或者断电,重启数据库以后,数据库中的数据应该是已经提交完成后的结果

  • 隔离性:针对多个并发用户同时操作,主要是排除其他事务对本次事务的影响
    在这里插入图片描述
    两个事务同时进行,其中一个事务读取到了另外一个事务还没有提交的数据,导致了在事务B的值出现异常

隔离所导致的一些问题

  • 脏读:指一个事务读取了另外一个事务未提交的数据
  • 不可重复读:在一个事务内读取表中的某一行数据,多次读取结果不同(这个不一定是错误,只是某些场合不对)
  • 虚读(幻读):是指一个事务内读取到了别的事务插入的数据,导致前后读取不一致

事务的隔离级别(4种)

  • RU 级别:(read uncommitted)读未提交:就是可以读到未提交的内容。因此,在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”
  • RC 级别:(read committed)读已提交:读已提交,就是读到已经提交了的内容。这是各种系统中最常用的一种隔离级别,也是SQL Server和Oracle的默认隔离级别。这种隔离级别能够有效的避免脏读,但除非在查询中显示的加锁,否则 “读已提交”只能避免“脏读”,并不能避免“不可重复读”和“幻读”。
  • RR 级别:(repeatable read) 可重复读:专门针对“不可重复读”这种问题而制定的隔离级别,它可以有效的避免“不可重复读”,并且它也是MySql的默认隔离级别。当事务启动时,不允许进行“修改操作(Update)或者删除操作(Delete)”,而“不可重复读”恰恰是因为两次读取之间进行了数据的修改,因此,“可重复读” 能够有效的避免“不可重复读”,但却避免不了“幻读”问题,因为幻读是由于“插入操作(Insert)”而产生的。
  • S 级别:(serializable) 串行化:数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行(每一行数据都进行了加锁)。这种级别下,“脏读”、“不可重复读”、“幻读”都不会出现,但是执行效率非常差,性能开销也最大,所以基本没人会用。

猜你喜欢

转载自blog.csdn.net/weixin_45608165/article/details/113458423