数据库典型冲突:
(1)丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。
(2)脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。
悲观锁先锁定资源,然后提交事务,释放锁。
乐观锁不锁定资源,提交的时候对资源进行比对,没有其他人改动就提交。
适用场景
· 乐观锁:适用于数据争用不严重/重试代价不大/需要相应速度快的场景。
· 悲观锁:适用于数据争用严重/重试代价大的场景。
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。
原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。
一致性:事务在完成时,必须使所有的数据都保持一致状态。
隔离性: 事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。
持久性
事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持.
事务有三种处理模型:
1.隐式事务是指每一条数据操作语句都自动地成为一个事务,事务的开始是隐式的,事务的结束有明确的
标记。
2.显式事务是指有显式的开始和结束标记的事务,每个事务都有显式的开始和结束标记。
3.自动事务是系统自动默认的,开始和结束不用标记。
并发操作有可能破坏事务的ACID特性并发操作带来的数据不一致性包括:丢失数据修改(重复修改导致覆盖)、读”脏”数据(读之后被修改)、不可重复读(读的过程被修改,导致重复读数据不一样)、产生幽灵数据(读取到被删除的数据)。
事务的提交和回滚:COMMIT/ROLLBACK
开始事务:连接到数据库,执行DML、DCL、DDL语句
结束事务: 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--事务中不能有任何修改数据库中数据的操作语句,这包括 insert、update、delete、create语句
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 次,以确定每一行记录的改变都不会造成从表数据在引用上的不完整。
典型的冲突有