MySQL事务隔离级别

1.事务存在的问题

1.1 脏读

如果一个事务A读取到了另一个未提交事务B修改过的数据B1,并使用了这个数据B1,然后事务B又回退了对该数据的修改至B0或又将该数据修改为其他值B2,对于A曾经读到这个数据B1,根本没有意义,那么这种情况就是脏读。

1.2 不可重复读

不可重复读是指在一个事务A内,多次读取同一个数据,前后结果不一致。

在这个事务A还没有结束时,另外一个事务B也访问了该同一数据。那么,在第一个事务A中的两次读数据之间,由于第二个事务B的修改(特指修改已存在的行),那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

1.3 幻读

幻读是指当事务不是独立执行时发生的一种现象。

例如第一个事务A对一个表中的数据先进行查询,发现主键为1的数据不存在,同时,第二个事务B也往表中插入主键为1的数据,然后事务A是看不到事务B插入的的数据的,但是当事务A也插入主键为1的数据,此时报主键冲突,明明看不见事务B的数据,但是却实实在在的冲突的,就好象发生了幻觉一样。

2. 事务隔离级

MySQL 包括的事务隔离级别如下:

  • 读未提交(READ UNCOMITTED)
    如果一个事务A读取到了另一个未提交事务B修改过的数据,那么这种隔离级别就称之为读未提交。
    存在的问题: 可能产生脏读

  • 读提交(READ COMMITTED)
    如果一个事务A只能读取到另一个已提交事务B修改过的数据,并且其它事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,那么这种隔离级别就称之为读提交。
    存在的问题: 可能产生不可重复读

  • 可重复读(REPEATABLE READ)
    一个事务只能读取到另一个已提交事务修改过的数据,但是第一次读过某条记录后,即使其它事务修改了该记录的值并且提交,之后该事务再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据。

    实现原理:使用MVCC(多版本并发控制),写时对已存在的表进行加锁(可以先简单理解成行加锁),并生成快照,事务A,事务B不可以同时修改表(前面的事务锁表,后面的事务等待释放锁),但由于是读不加锁,可以一个事务写,一个事务读,详细参考:《MYSQL可重复读及原理、快照读和当前读》
    存在的问题: 可能产生幻读

  • 串行化(SERIALIZABLE)
    如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。那么这种隔离级别就称之为串行化。
    实现原理:完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
    存在的问题: 不会存在bug,只是每次表级锁导致效率低下。

MySQL 事务隔离级别可能产生的问题如下表所示:

隔离级别 脏读 不可重复读 幻读
READ UNCOMITTED
READ COMMITTED ×
REPEATABLE READ × ×
SERIALIZABLE × × ×

你可能感兴趣的:(mysql,mysql,数据库,java)