悲观锁、乐观锁、事务和阻塞

数据库典型冲突

1)丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。

2)脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。

悲观锁先锁定资源,然后提交事务,释放锁。

 

乐观锁不锁定资源,提交的时候对资源进行比对,没有其他人改动就提交。

适用场景

·       乐观锁:适用于数据争用不严重/重试代价不大/需要相应速度快的场景。

 

·       悲观锁:适用于数据争用严重/重试代价大的场景。

数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 

一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。

原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

一致性:事务在完成时,必须使所有的数据都保持一致状态。

隔离性: 事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

持久性

 

事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持.

事务有三种处理模型:

1.隐式事务是指每一条数据操作语句都自动地成为一个事务,事务的开始是隐式的,事务的结束有明确的

标记。

2.显式事务是指有显式的开始和结束标记的事务,每个事务都有显式的开始和结束标记。

3.自动事务是系统自动默认的,开始和结束不用标记。

并发操作有可能破坏事务的ACID特性并发操作带来的数据不一致性包括:丢失数据修改(重复修改导致覆盖)、读数据(读之后被修改)、不可重复读(读的过程被修改,导致重复读数据不一样)、产生幽灵数据(读取到被删除的数据)。

事务的提交和回滚COMMIT/ROLLBACK

    开始事务:连接到数据库,执行DMLDCLDDL语句

    结束事务: 1. 执行DDL(例如CREATE TABLE),DCL(例如GRANT),系统自动执行COMMIT语句

          2. 执行COMMIT/ROLLBACK

          3. 退出/断开数据库的连接自动执行COMMIT语句

          4. 进程意外终止,事务自动rollback

          5. 事务COMMIT时会生成一个唯一的系统变化号(SCN)保存到事务表

   保存点(savepoint): 可以在事务的任何地方设置保存点,以便ROLLBACK

相关SQL:

SET TRANSACTION----设置事务属性

SET CONSTRAINT -----设置约束

SAVEPOINT ------------建立存储点

RELEASE SAVEPOINT --释放存储点

ROLLBACK---------------回滚

COMMIT------------------提交

建立事务:

SET TRANSACTION READ ONLY--事务中不能有任何修改数据库中数据的操作语句,这包括 insertupdatedeletecreate语句

SET TRANSACTION READ WRITE--默认设置,该选项表示在事务中可以有访问语句、修改语句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

 

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE--serialzable可以执行DML操作

SQL例子:

SET TRANSACTION READ ONLY

 

select * from trwtcTest1 for update

 

阻塞

引起阻塞的几种常见情况

 

1 DML 语句引起阻塞 
2)外键没有创建索引

4 个常见的 dml 语句会产生阻塞:

1 INSERT

2 UPDATE

3 DELETE

4 SELECT…FOR UPDATE

 

可以通过发出 select ... for update nowait 的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified.

如果系统中有主,外键引用关系,并且满足一下三个条件中的任意一个,那么就应该考虑给外键字段创建索引,否则系统的性能可能会下降甚至阻塞。

1 主表上有频繁的删除操作

2 主键上有频繁的修改操作。

3 业务上经常会出现主表和从表做关联查询的情况。

如果主表上经常出现这样的删除或者是对主键列进行修改的操作,或者每次操作的记录数很多,都将会造成从表长时间被锁定,而影响其他用户的正常操作。

比如主表每次删除 1000 行数据,它就需要扫描从表 1000 次,以确定每一行记录的改变都不会造成从表数据在引用上的不完整。

 

 

 

 

典型的冲突有

posted @ 2019-02-27 15:47  大尾巴贝贝  阅读(404)  评论(0编辑  收藏  举报