概念:

并发事务带来的问题:

更新丢失:事务A和事务B同时操作,事务B覆盖了事务A做的操作,导致事务A的更新丢失了

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_数据

脏读:事务A读取到事务B还未提交的事务

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_java_02

不可重复读:

  • 事务A在统一事务的不同时间段内,读取统一数据,得到的值不一样(读取到其他事务修改的值)

幻读:

  • 事务A再同一事务的不同时间段内,第一次读取的结果行与第2次读取的结果行不一样(读取到其它事务新增的内容)

事务的隔离级别:

begin前先设置隔离级别:set session transaction isolation level ××;

e.g:设置隔离级别为读已提交:

set session transaction isolation level read committed

(切记,事务开始之前一定要先begin,确认事务操作符合预期再commit,不符合预期rollback,否则忘了begin直接操作代码的话数据更改了想撤回都撤回不了)

SQL标准为事务定义了不同的隔离级别,从低到高依次是:

读未提交(READ UNCOMMITTED):

  • 能读取到其他事务未提交的数据

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_数据库_03

输出的这个表的结果是并没有提交的,rollback之后'李四' 的 'money'的值仍然是为1000。 


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_Mysql事务隔离级别读已提交_04

 此时是最初始的状态,并未开始事务。


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_Mysql事务隔离级别读已提交_05

事务开始执行,并未提交。此时mysql设置了隔离‘读未提交(READ UNCOMMITTED)‘级别后查询到了并没有提交的表格的数据 


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_数据库_06

 接着回滚(回滚之后依旧没有提交),两边再查询表数据,查询出回滚后的值

读已提交(READ COMMITTED):

  • 能读取到其他事务已提交的数据,与读未提交同理

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_大数据_07

 此时事务是初始状态,没有进行操作


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_大数据_08

接下来进行事务操作,提交了改变后的数据,此时MySQL里面读取数据,读取到了已提交的数据 


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_大数据_09

此时右边进行了事务的操作但并未进行提交,左边查询数据依旧是上一步已提交的数据 


可重复读(REPEATABLE READ):数据库的默认隔离级别

  • 事务A在同一事务的不同时间段内,读取同一行数据,得到的值一样(即便其它事务修改了该值)

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_Mysql事务隔离级别读已提交_10

初始状态 


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_Mysql事务隔离级别读已提交_11

右边直接操作第8行(不要begin后再操作,否则重新开始了该事务),将该值修改为2000后commit,左边再读取,可以看到的是查询到的依旧是1000,没有受到其他事务(更改了第8行的数据并提交)的影响,因为此时左边还在该事务内。


Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_数据_12

左边commit提交该事务,此时左边的状态就在这个事务之外了,因此执行右边修改后的值左边再查询会看到是查询到的是修改后的值 


串行化(SERIALIZABLE):

  • 事务依次执行,不存在并发问题

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_大数据_13

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_java_14

 执行commit。发送之后,左边立马显示结果


归纳:

Mysql事务隔离级别读已提交 mysql 事务隔离级别的使用_数据_15

  • 事务的隔离级别越低,可能出现的并发异常越多,但是通常而言系统能提供的并发能力越强。