Loading

MySQL中事务详解

转自:https://blog.csdn.net/J080624/article/details/53995591

【1】事务的隔离级别

一个事务与其他事务隔离的程度称为隔离级别。数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱。

数据库系统必须具有隔离并发运行各个事务的能力, 使它们不会相互影响, 避免各种并发问题。

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题。

五种隔离级别:DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。

Oracle 支持的2 种事务隔离级别:READ_COMMITTED, SERIALIZABLE。Oracle 默认的事务隔离级别为: READ_COMMITTED。

MySQL支持4 种事务隔离级别:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE。MySQL 默认的事务隔离级别为: REPEATABLE_READ

1、DEFAULT(读提交)

这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。大部分数据库的默认级别都是READ_COMMITTED(读取已提交)。

2、READ_UNCOMMITTED(读取未提交)

这是事务最低的隔离级别,允许当前事务读取未被其他事务提交的变更。这种隔离级别会产生脏读,不可重复读和幻读。

产生脏读场景:A事务读取一个字段,但是这个字段被另外一个事务更新却未提交,再次读取该字段时如果另外一个事务回滚则出现了脏读现象(读到的数据与第一次,数据库中的数据都不同)。

产生不可重复读场景:A事务读取一个字段,但是这个字段被另外一个事务更新并提交,再次读取该字段值不一样则出现了不可重复读现象(同一个事务中,不能保证读取的字段值相同)。

产生幻读场景:A事务读取一个字段集合,但是这个表被另外一个事务更新并提交(如插入了几行),再次读取该表可能会多几行则出现了幻读现象。

解释:或者说事务A开启事务,查询当前表-目标数据不存在;事务B开启事务插入一条新数据(id为主键);事务A 插入和事务B一样的数据,会出现锁等待超时现象。事务B提交后,事务A再次尝试插入,出现Duplicate entry…事务B很诧异,明明查询出来不存在将要插入的数据

3、READ_COMMITTED(读取已提交)

保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。可以避免脏读,但不可重复读和幻读的现象仍然可能出现。

不可重复读

A事务读取一个字段,但是这个字段被另外一个事务更新并提交,再次读取该字段值不一样则出现了不可重复读现象(同一个事务中,不能保证读取的字段值相同)。

解释举例:就是对于一个数A原来是50,然后提交修改成100,这个时候另一个事务在A提交修改之前,读取到了A是50,刚读取完,A就被修改成100了,这个时候另一个事务再进行读取发现A就突然变成100了

幻读

读取一个字段,但是这个表被另外一个事务更新并提交(如插入了几行),再次读取该表可能会多几行则出现了幻读现象。

4、REPEATABLE_READ(可重复读)

确保事务可以多次从某行记录的一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新。这种事务隔离级别可以防止脏读,不可重复读,但是可能出现幻读

它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了在一个事务过程,读取的数据不会发生变化(即使数据库中的数据在该事务过程中发生了变化)。

幻读

读取一个字段集合,但是这个表被另外一个事务更新并提交(如插入了几行),再次读取该表可能会多几行则出现了幻读现象。

5、SERIALIZABLE :(可串行化)

在并发情况下和串行化的读取的结果是一致的,没有什么不同。这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。

除了防止脏读,不可重复读外,还避免了幻读。但性能十分低下!

6、什么是脏读、不可重复读和幻读?

脏读: 对于两个事务 T1, T2。T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的,也就是脏数据。

不可重复读:对于两个事务 T1, T2。 T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。

幻读:事务T1读取一条指定where条件的语句,返回结果集。此时事务T2插入一些新记录,恰好满足T1的where条件。然后T1使用相同的条件再次查询,结果集中可以看到T2插入的记录,这些多出来的新纪录就是幻读。

不可重复读重点是在update,即事务前后对比特定数据内容的修改。而幻读是insert和delete,即事务前后数据结果集的对比。

7、事务隔离级别与存在问题

隔离级别存在问题
READ UNCOMMITTED 脏读、不可重复读、幻读
READ COMMITTED 不可重复读、幻读
REPEATABLE READ 幻读
SERIALIZABLE

 

MySQL默认事务隔离级别为REPEATABLE_READ

事务的隔离级别要得到底层数据库引擎的支持, 而不是应用程序或者框架的支持。需要注意的是事务的隔离级别和数据库并发性是成反比的,隔离级别越高,并发性越低。

 

posted @ 2022-09-14 09:08  Allfuture  阅读(148)  评论(0编辑  收藏  举报