数据库并发可能存在的问题和数据库隔离级别

版权声明:啊 这是啥 https://blog.csdn.net/huangyueranbbc/article/details/84304682

数据库并发操作存在的异常情况:
1.更新丢失(LostUpdate):
A和B事务并发执行,A事务执行更新后,提交;B事务在A事务更新后,B事务结束前也做了对该行数据的更新操作,然后回滚,则两次更新操作都丢失了。

第一类丢失更新(回滚丢失,Lost update)。
在事务A期间,事务B对数据进行了更新;在事务A撤销之后,覆盖了事务B已经提交的数据。
SQL92没有定义这种现象,标准定义的所有隔离界别都不允许第一类丢失更新发生。

第二类丢失更新(覆盖丢失/两次更新问题,Second lost update)。
在事务A期间,事务B对数据进行了更新;在事务A提交之后,覆盖了事务B已经提交的数据。
第二类丢失更新,实际上和不可重复读是同一种问题。

2.脏读取(DirtyReads):
A和B事务并发执行,B事务执行更新后,A事务查询B事务没有提交的数据,B事务回滚,则A事务得到的数据不是数据库中的真实数据。也就是脏数据,即和数据库中不一致的数据。

3.不可重复读取(Non-repeatableReads):
 A和B事务并发执行,A事务查询数据,然后B事务更新该数据并提交,A再次查询该数据时,发现该数据变化了。

4.幻读(PhantomReads):也称为幻像(幻影)。
A和B事务并发执行,A事务查询数据,B事务插入或者删除数据并提交,A事务再次查询发现,结果集中,有以前没有的数据或者以前有的数据消失了。

为了避免上面出现几种情况在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同。
1. READ-UNCOMMITTED未授权读取/未提交读
允许脏读取但不允许更新丢失。
如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。通过“排他写锁”实现。

2. READ-COMMITTED授权读取/提交读
允许不可重复读取但不允许脏读取。
更新语句提交以后别的事务才能读到这个改变。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。通过“瞬间共享读锁”和“排他写锁”实现,
在此隔离级下,SELECT命令不会返回尚未提交(Committed)的数据,也不能返回脏数据。

3. REPEATABLE-READ可重复读取
禁止不可重复读取和脏读取。但是有时可能出现幻影数据
在同一个事务里面先后执行同一个查询语句的时候,确保得到的结果是一样的。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。通过“共享读锁”和“排他写锁”实现,
在此隔离级下,用SELECT命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。

4. SERIALIZABLE串行/可串行读。
事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。

猜你喜欢

转载自blog.csdn.net/huangyueranbbc/article/details/84304682