事务(ACID)
用一个业务举例说明,用户a给用户b转账,a收到100,b失去100
原子性:事务的操作,要不都成功,要不都失败(就是要不a转账成功,b收到款了,要不a转账失败,b没收到款)
一致性:事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处于一致性状态。
隔离性:事务的隔离性是指在并发环境中,并发的事务时相互隔离的,一个事务的执行不能不被其他事务干扰。不同的事务并发操作相同的数据时,每个事务都有各自完成的数据空间,即一个事务内部的操作及使用的数据对其他并发事务时隔离的,并发执行的各个事务之间不能相互干扰。
持久性:一旦事务提交,那么它对数据库中的对应数据的状态的变更就会永久保存到数据库中
事务的并发问题
脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。
幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
不可重复度和幻读区别:
不可重复读的重点是修改,幻读的重点在于新增或者删除。
隔离级别
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同,分别是:
读未提交,读已提交,可重复读取和串行化
--查看数据库默认的隔离级别 select @@tx_isolation;
--设置隔离级别 set tx_isolation=‘read-uncommitted’读未提交
--A用户
start TRANSACTION --开启事务
update account set name='zb' where id=1
select * from account
--B用户
start TRANSACTION --开启事务
select * from account
--A用户
update account set name='zz' where id=1
commit --提交
select * from account
--B用户
select * from account
commit --提交
select * from account
insert into account(name,id) valuses('dd',4)
commit
--A用户
select * from account
读未提交:可以理解为能读取到未提交的事务,如用户a进行错误修改之后并未提交,b进行查看也可以看到修改的数据,就出现了脏读的情况。
读已提交:可以理解为只能读取到以提交的事务,只有a用户进行修改数据并提交后,b用户才可以查看到数据的修改情况,但会造成b用户读取同一条数据时出现不同的结果,就是不可重复读的情况
可重复读:(MySQL默认级别):就是保证在事务处理过程中,多次读取同一个数据时,其值都和事务开始时刻是一致的。b用户在事务开始的时候查看数据是什么样的,即使a用户对数据进行修改提交事务,也不会影响b事务的查看结果,但当b事务提交后,就可以看到a事务对数据的修改,但是当b用户对数据进行增加的时候,a用户就可以看到数据增多,就是出现幻读的情况。
串行化:是最严格的事务隔离级别,它要求所有事务被串行执行,即事务只能一个接一个的进行处理,只有当a用户提交事务后,b用户才可以对数据进行修改的事务,不能并发执行。