事务ACID属性说明
原子性(Atomicity) :在当前开启的事务中,所有的操作要么全部成功,要么全部失败,不允许有部分成功或者失败的场景发生。程序执行过程中发生异常后回滚操作主要由undo log日志来完成数据回滚操作。
一致性(Consistent):主要看启动这个事务的最终目的,需要其他3个特性都保证的前提下保证业务逻辑也需要正确。
隔离性(Isolation):多个事务并发执行相同的数据场景时,需要保证各个事务之间操作各自的数据
时相互不影响。隔离性主要由mysql的各种锁和mvcc机制来实现。
持久性(Durable) :事务提交之后,数据将会得到永久保存,主要由redo log启动时补偿刷新数据以及i/o空闲时随机刷盘实现。(并不是事务提交就立马会把数据刷入磁盘)
并发事务存在的问题:
脏写:A、B两个事务同事修改同一条数据时,最后提交的事务会修改之前已经提交过的事务的数据。
脏读:B事务读取到了A事务修改但是未提交的数据。
不可重复读:A事务在不未提交前有其他事务修改数据并提交后,A事务多次查询得到的结果不一致。
幻读:A事务在第一次查询的时候得到1条数据,在这个过程中B事务又增加了一条数据,A事务第二次去读取时能读取到新增的那条数据。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(Read uncommitted)
| 可能 | 可能 | 可能 |
读已提交(Read committed)
| 不会 | 可能 | 可能 |
可重复读 (Repeatableread)
| 不会 | 不会 | 可能 |
可串行化 (Serializable)
| 不会 | 不会 | 不会 |
其他情况相对简单,这里只验证一次幻读:
select * from account where id>5;
在客户端A开启事务
begin ;
select * from account
where age>30;
在B客户端开启一个事务并插入一条数据
begin ;
INSERT INTO `tangqin`.`account` (`name`, `name_cn`, `age`, `balance`, `create_data`, `last_update_date`)
VALUES ('wangwu', '王五', 55, 200, DEFAULT, DEFAULT);
commit ;
这时再去A客户端执行更新操作
update account set balance=balance+100
where age=55;
这个时候再查询数据
select * from account
where age>30;
以上是本人对mysq事务问题的总结,如有疑问欢迎各位大佬指出!