Mysql事务与锁的一些记录

### 隔离级别

1. 读未提交(Read Uncommitted)允许脏读,就是在该隔离级别下,可能读到其他会话未提交事务修改的数据,存在脏读、不可重读读、幻读的问题。

2. 读已提交(Read Committed)只能查询到已提交的数据。这是 Oracle 数据库默认的事务隔离级别。存在不可重读读、幻读的问题。

3. 可重复读(Repeatable Read)就是在一个事务里相同条件下,无论何时查到的数据都和第一次查到的数据一致。这是 MySQL 数据库 InnoDB 引擎默认的事务隔离级别。在范围查询时存在幻读的问题。

4. 串行化(Serializable)是最高的事务隔离级别,它严格服从 ACID 特性的隔离级别。所有的事务依次逐个执行,事务之间互不干扰,该级别可以防止脏读、不可重复读以及幻读。但每个事务读数据时都需要获取表级的共享锁,导致读和写都会阻塞,性能极低。

## insert、update、delete 会自动加锁

1. 如果遇到其他事务对同一记录有未提交的insert,update,delete 操作,则会等待其他事务执行完毕释放锁后继续操作。

### 锁+事务

1. 事务A,查询余额为10,不加锁,更新B不开启事务修改余额为20,事务A余额增加10,最终余额为30

2. 事务A,查询余额为10,加锁,更新B不开启事务余额增加10,开始等待事务A提交,如果事务A提交,最终更新B余额为20。事务A一直未提交,更新B失败。

3. 事务A,查询余额为20,加锁;事务B查询余额为20,加锁;事务A更新余额为30,事务B余额+10 (失败,锁竞争失败);

    1. 事务A提交,事务B提交;最终余额为30;

    1. 事务A提交,事务B不提交;最终余额为30;因为update失败,不会产生影响

4. 回滚失败的情况

    1. 事务A,查询余额为10,加锁;

    2. 事务B查询余额为10,加锁;

    3. 事务B更新余额为20,事务A余额+50;事务B更新成功;事务A报错(Deadlock found when trying to get lock; try restarting transaction),此时事务A已经没有了。

    4. 事务A余额+50;

        1. 事务B回滚,事务A更新成功,事务A回滚;最终余额为60;

        2. 事务B提交,事务A更新成功,事务A回滚;最终余额为70;

    5. 事务A回滚失败。原因为 事务A 在第三步就没有了。