葡京网投哪个正规 > 新葡亰-数据 > 浅析Oracle中的事务,数据库设计与事务处理葡京网投哪个正规:

原标题:浅析Oracle中的事务,数据库设计与事务处理葡京网投哪个正规:

浏览次数:59 时间:2019-11-30

事务(transaction)其实就是一序列数据库命令,他们可以组合在一起当做一个单一逻辑单元

1. 什么是事务

事务

  Transaction,数据库操作序列组成的单个逻辑执行单元,要么全部执行,要么全不执行(同生共死)。事务是数据库运行中的一个逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。事务需手动启动和结束,事务是 恢复 和 并发控制 的基本单位。
ζ声明创建

   begin transaction 事务名|(事务名称)变量
          with mark
       SQL处理语句

 其中,begin使@@TRANCOUNT加1,commit/rollback使@@TRANCOUNT减1,但是回滚到savapoint不影响其值。通过@@TRANCOUNT可以查看当前活动中的事务数量,一个事务完整执行完毕,@@TRANCOUNT应为0;
ζ保存点

   save transaction 保存点名|(保存点名称)变量   

ζ嵌套
  只有显式事务可以嵌套。
ζ提交
·  显式提交:commit transaction 事务名|(事务名称)变量;
·  自动提交:执行 DCL或DDL 语句(导致事务立即提交),或程序正常退出;
葡京网投哪个正规 , ζ回滚
·  显式回滚:rollback transaction 事务名|(事务名称)变量|保存点名|(保存点名称)变量;
·  自动回滚:系统错误或强行退出;
 注:提交和回滚都会结束当前事务,commit之后不能再rollback,但可以采用闪回flashback恢复数据。检查点机制周期地检查事务日志(数据操作和任务操作信息)检查事务的执行状态。

在一个事务被标记为完成之前(commited),任何改变可以被回滚(rolled back)

在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个工作单元操作,要么一个也不执行。

优点
  • 维护数据库数据的 正确性、完整性、一致性、可恢复性;
  • 简化错误恢复,可靠性高;

例子:转账,它可以包括(减少发送钱账户的金额量,增加收款人的金额量,给发送方和接收方都增加交易记录)

如:网上转帐就是典型的要用事务来处理,用以保证数据的一致性。

特征:ACID属性
  • 原子性 Atomicity:事务是应用中不可再分的最小逻辑执行单位体;
  • 一致性 Consistency:事务结束后,数据库内的数据是合法正确的;
  • 隔离性 Isolation:并发执行的事务之间相互独立、互不干扰;
  • 持续性 Durability:持久性,Persistence,事务提交后,数据是永久性的、不可回滚;

 其中,C 是终极目标, AID 是方法手段。

注意事项

  • 事务宜短,避免使用嵌套、while循环、DDL;
  • 避免用户交互操作;

参考

  • 数据库事务初识;
  • 我理解的数据库事务 - 简书;

如果连接被打断,或者说一些操作失败了,所有的操作都需要被回滚

2. 事务特性

并发

 数据库支持数据共享,允许多个用户程序并行访问数据,引起并发操作 (Concurrency),即多用户或多事务对同一数据( 同一时间间隔 )进行操作,关键是如何对系统内的多个活动(进程)进行切换。

→ Total failure is better than partial failure

SQL92标准定义了数据库事务的四个特点:

优缺点
  • 对有限物理资源强制多用户共享,复用提高效率;
  • 数据不一致性,破环数据的完整性;

 

  • 原子性(Atomicity):一个事务里面所有包含的SQL语句是一个执行整体,不可分割,要么都做,要么都不做。
  • 一致性(Consistency):事务开始时,数据库中的数据是一致的,事务结束时,数据库的数据也应该是一致的。
  • 隔离性(Isolation):是指数据库允许多个并发事务同时对其中的数据进行读写和修改的能力,隔离性可以防止事务的并发执行时,由于他们的操作命令交叉执行而导致的数据不一致状态。
  • 持久性 (Durability) : 是指当事务结束后,它对数据库中的影响是永久的,即便系统遇到故障的情况下,数据也不会丢失。
并发 .vs. 并行 (Parallelism):

 并行性允许多个程序(同一时刻)在不同的CPU上运行。 从微观角度,并行性是多处理机、多进程在同一时刻同时运行,物理上的同时发生,并发性是单处理机下、多个进程在同一时间间隔内运行,逻辑上的同时发生;从宏观角度,并发是表现为并行的。并行性包含同时性和并发性,并行性是并发性的特例。
参考:并行和并发的区别联系;
     并发操作 - 数据不一致 + 并发控制;


每一个事务的终止信号都是通过commit或者roll back来传达的,没有commit,我们做出的改变不会被保存

一组SQL语句操作要成为事务,数据库管理系统必须保证这组操作的原子性(Atomicity)、一致性(consistency)、隔离性(Isolation)和持久性(Durability),这就是ACID特性。

并发操作破坏事务的隔离性,导致如下问题:

  • 丢失修改:事务A对数据的修改覆盖了事务B对数据的修改,事务B对数据的修改丢失;
  • 脏读:事务A正在对数据访问修改还未提交,此时事务B访问该数据;
  • 不可重复读:在同一事务A中多次读取数据时,事务B对数据修改,导致多次读取的数据不一致;
  • 幻读:事务A读取结果集,事务B对结果集增删改,事务A再次查询结果集时,发现数据新增/丢失/修改;

注:幻读和不可重复读都是读取已提交事务的结果(脏读是读取未提交事务的结果)。不可重复读针对同一个数据项,幻读针对一批数据整体。
参考:上述问题解释及解决方法;
  数据库通过 封锁机制(锁+封锁协议)来解决并发访问造成的数据不一致,同步多个用户同时对同一个数据块的访问的一种机制,保证数据库完整性和一致性。锁之间存在兼容性问题,由数据库引擎的 锁管理器葡京正网网投 ,在内部管理。系统的自动锁定管理机制实现动态优化加锁。行版本控制利用类时间戳列(行版本列)完善锁机制。锁定和行版本控制可以防止用户读取未提交的数据,也可以防止多用户同时更改同一数据。
锁的自动优化:锁升级
  Lock Escalations,将许多较细粒度的锁转换成数量更少的较粗粒度的锁的过程,多数情况下将众多行锁升级为一个表锁,削减系统开销,但会增加并发争用资源,甚至引发死锁。数据库引擎可以为同一语句执行行锁定和页锁定。
参考:锁升级的问题研究; 关于DB2锁升级相关问题的探讨;

但其实Sesssions都是有自动提交功能(auto-commit)的,也就是任何命令都能被马上提交,不需要roll back和commit,这种auto-commit方式都是被默认的(set sutocommit = 0 关闭autocommit)

3. 数据异常

事务隔离级别

 事务并发与隔离级别关联。
·  读未提交数据:Read Uncommitted
  可能引发脏读、不可重复读、幻读;最低的事务隔离级别,
·  读已提交数据:Read Committed
  可能引发不可重复读、幻读,避免脏读;多数数据库的默认隔离级别;
·  可重复读:Repeatable Read
  可能引发幻读,避免脏读、不可重复读;MySql的默认隔离级别;
·  可串行化:Serializable
  不会引发上述问题;最高的事务隔离级别,强制事务顺序串行执行,对每行数据加锁(锁表),会引发超时和锁竞争,耗资源多、损失并行度、性能低;
 参考:数据库事务隔离级别;

→ START TRANSACTION or BEGIN

因为Oracle中支持多个事务并发执行,所以会出现下面的数据异常。

分类

-=- 锁定模式 -=-
·共享锁(Share Lock,S锁, 读锁)
  允许并发事务在封闭式并发控制下读取资源但不能更改数据,保证在事务T释放数据对象obj上的锁之前,其他事务不能修改、但可以读取obj,只能在obj上加读锁、不能加写锁,select;
  查询操作通常只请求S锁;
·排他锁(Exclusive Lock,X锁, 写锁, 独占锁)
  防止并发事务对同一资源同时更新,保证在事务T释放数据对象obj上的锁之前,其他事务不能读取和修改(insert、update、delete)obj、更不能在obj上加锁,排他锁不与其他任何锁兼容。;
  修改操作通常请求X锁和S锁;
·更新锁U锁)
  可防止常见的死锁,即在多个事务锁定、读取资源以及随后可能进行的资源更新导致死锁。更新锁每次只能分配给一个事务,若要修改资源,更新锁会变成排他锁,否则变为共享锁 ;
·意向锁I锁)
  I 锁包括意向共享锁 IS、意向排他锁 IX、意向排他共享锁 SIX(S+IX),用于建立锁的层次结构,对任一结点加锁时,必须先对它的上层结点加意向锁,以保护锁层次结构中的底层资源(上的共享或排它锁),提高锁冲突检测性能,因为数据库引擎仅在表级检查意向锁,确定事务是否能安全获取表上的锁,而不需检查表中的每行或每页上的锁以确定事务是否可以锁定整个表。
  SQL-Server中意向锁初识;
·架构锁(Sch锁)
  用于依赖表架构的操作。数据库引擎在编译和查询时使用架构稳定性 (Sch-S) 锁,在表DDL操作、某些DML操作时使用架构修改 (Sch-M) 锁。
·键范围锁(Range锁)
  在使用可序列化隔离级别时用于保护查询读取的行的范围,可以防止幻读(幻象插入/删除)。键范围锁放置在索引上,指定开始与结束的索引键值。
-=- 锁定对象 -=-
·行级锁:行,InnoDB具有行锁定机制;
·表级锁:表;
封锁粒度,Granularity,封锁对象的大小。封锁对象可以是逻辑单元,也可以是物理单元。封锁粒度与系统的并发度相关,封锁粒度越小,并发度越高,开销越大。选择封锁粒度时应该综合考虑封锁开销和并发度两个因素,查询优化器在编译执行计划时通常会选择正确的锁粒度。

BEGIN;

3.1 脏读

3级封锁协议 - Locking Protocol

·  一级
    内容:事务T读数据不加锁,修改数据对象A之前必须对其加X锁,直到事务结束才释放;
    作用:解决"丢失修改"问题,保证事务T是可恢复的,但不能避免脏读和不可重复读;
·  二级
    内容:一级协议X锁 + 事务T读取数据对象A之前必须对其加S锁,读完后立即释放;
    作用:解决"丢失修改" + "脏读"问题,但不能避免不可重复读;
·  三级
    内容:一级协议X锁 + 事务T读取数据对象A之前必须对其加S锁,直到事务结束才释放;
    作用:解决"丢失修改" + "脏读" + "不可重复读"问题;
 其中,事务结束包括commit和rollback。每一级协议的X锁均在事务结束后再释放,一级封锁协议读数据时并不加锁、仅关注事务对数据的修改,二、三级封锁协议关注事务对数据的读取。
参考:数据库并发问题及封锁协议; 封锁机制;

UPDATE accounts SET balance = balance - 100.00 WHERE acc_nr = 254231426;

当一个事务修改数据时,另一事务读取了该数据,但是第一个事务由于某种原因取消对数据修改,使数据返回了原状态,这是第二个事务读取的数据与数据库中数据不一致,这就叫脏读。

封锁后遗症
  • 活锁 (Live Locks)

  多个事务请求对同一数据封锁,某一事务总是处于等待的现象。事务T1封锁数据R,事务T2请求封锁R,于是T2等待。T3也请求封锁R,当T1释放对R的封锁后系统首先批准了T3的请求,T2仍然等待。然后T4又请求封锁R,当T3释放了对R的封锁后系统又批准了T4的请求,…,T2有可能永远等待。
方法:事务排队,先来先服务。

  • 死锁 (Dead Locks)

  也称阻塞,多个事务交错相互等待对方释放资源,循环依赖对方造成资源读写拥挤堵塞的情况,耗时耗资源。事务T1和T2都需要数据Rl和R2,当前Tl封锁数据R1、T2封锁数据R2;然后T1又请求封锁R2、T2又请求封锁Rl;因T2已封锁R2,故T1等待T2释放R2上的锁,因T1已封锁R1,故T2等待T1释放R1上的锁。由于Tl和T2都没有获得需要的全部数据,所以它们不会结束、只能互相等待。
注:区分正常阻塞和死锁的区别。
原因

  • 系统资源不足,资源分配不当、竞争(不可剥夺)资源;
  • 进程运行推进的顺序不合适;
  • 信号量、临时资源利用不当;

必要条件:缺一不可

  • 互斥条件:Mutual exclusion,在一段时间内某个资源只能被一个进程占用;
  • 请求保持条件:Hold and wait,一个进程因请求资源而阻塞时,同时对已获得的资源保持不放;
  • 不剥夺条件:No pre-emption,不能强行剥夺进程已经获得的资源;
  • 循环等待条件:Circular wait,多个进程形成头尾相接的进程-资源环形链,循环等待资源;

方法:(防 + 治)结合;
   数据库引擎的 死锁监视器 定期主动检测陷入死锁的任务。首先引入 安全状态 :系统能按某种顺序为每个进程分配所需资源并且依次地运行完毕,反之系统是不安全的。安全状态一定不会发生死锁,不安全状态不一定会发生死锁,死锁时系统一定处于不安全状态。
   按同一顺序访问对象、缩短事务持锁时间(避免事务中的用户交互、使用较低的隔离级别、保持事务简短)、行版本控制、绑定连接均可以有效防止死锁问题,其中绑定会话有利于在同一台服务器上共享相同的事务和锁以实现多个会话之间协调操作。
■   **预防**死锁
   实质是破坏产生死锁的四个必要条件。实现简单,但是限制条件严格、资源利用率低,破坏系统的并行性、并发性,降低系统性能。

  • 资源静态分配法:破坏请求和保持条件,进程所需资源一次性分配完毕;
  • 可剥夺资源:破坏不可剥夺条件,系统让资源占有者主动释放资源;

■    **避免**死锁
   实质是系统允许前三个条件存在,但是在资源的动态分配过程中,预先计算资源分配的安全性以防止系统进入不安全状态(不会形成环形等待的封闭进程链),从而避免死锁。支持多进程并行执行。

  • 有序资源分配法:破坏环路等待条件,系统为资源编号,进程按编号升序请求资源,释放则相反;
  • 银行家算法:1968年由Dijkstra E.W提出,针对资源分配。限制条件少、资源利用率高,但开销大;

检测和解除死锁
   实质是允许系统在运行过程中发生死锁,但系统可及时检测出死锁的发生并精确确定与死锁有关的进程和资源,然后解除之。
[1]. 检测

  • 首先为每个进程、每个资源指定唯一号码,建立进程等待表和资源分配表;

[2]. 解除

  • 剥夺资源:从其它进程剥夺足够数量的资源给死锁进程;
  • 撤销进程:直接撤消死锁进程或撤销死锁优先级低的进程或撤消回滚代价最小的进程;

参考

  • 学习笔记:数据库——事务和锁;
  • 学习数据库事务 - 锁;
  • 银行家算法详解;

 

UPDATE accounts SET balance = balance + 100.00 WHERE acc_nr = 676535301;

如:事务T1修改了一条数据,但是还未提交,事务T2恰好读取到了这条修改后了的数据,此时T1将事务回滚,这个时候T2读取到的数据就是脏数据。

INSERT INTO transfers (acc_nr, amount, reference) VALUES (254231426, -100.00, ’Dentist’);

3.2 不可重复读

INSERT INTO transfers (acc_nr, amount, reference) VALUES (676535301, 100.00, ’John Smith’);

是指一个事务读取数据库中的数据后,另一个事务则更新了数据,当第一个事务再次读取其中的数据时,就会发现数据已经发生了改变,这就是不可重复读取。不可重复读取所导致的结果就是一个事务前后两次读取的数据不相同。

COMMIT;

如:事务T1读取一行记录,紧接着事务T2修改了T1刚刚读取的记录,然后T1再次查询,发现与第一次读取的记录不同。

 

3.3 幻读

同时事务:

如果一个事务基于某个条件读取数据后,另一个事务则更新了同一个表中的数据,这时第一个事务再次读取数据时,根据搜索的条件返回了不同的行,这就是幻读。

复杂情况:多种同时事务

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

情况1:按顺序执行事务

事务中遇到的这些异常与事务的隔离性设置有关,事务的隔离性设置越多,异常就出现的越少,但并发效果就越低,事务的隔离性设置越少,异常出现的越多,并发效果越高。

  很简单去实行,在一些情况下工作的很好

4. 事务隔离级别

  但是有时过慢了:

针对读取数据时可能产生的不一致现象,在SQL92标准中定义了4个事务的隔离级别:

    CPU可以保持空闲当I/O转换过程中,反之亦然

隔离级别 脏读 不可重复读 幻读
Read uncommitted(读未提交)
Read committed(读已提交)
Repeatable read(可重复读)
Serializable(串行读)

    慢的语句可能会阻碍快的那个

Oracle默认的隔离级别是read committed。

    事务可能需要去等待用户输入

Oracle支持上述四种隔离级别中的两种:read committed 和serializable。除此之外,Oralce中还定义Read only和Read write隔离级别。

情况2:事务的交错执行

Read only:事务中不能有任何修改数据库中数据的操作语句,是Serializable的一个子集。

  等待时间一半都减少特别明显了

Read write:它是默认设置,该选项表示在事务中可以有访问语句、修改语句,但不经常使用。

  在单命令事务中也能进行工作(分裂成多种更小的操作)

设置隔离级别

  但是难以正确实施进行

设置一个事务的隔离级别:

  这就是DBMS所做的事

  • SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  • SET TRANSACTION READ ONLY;
  • SET TRANSACTION READ WRITE;

 

注意:这些语句是互斥的,不能同时设置两个或两个以上的选项。

ACID规则:

设置单个会话的隔离级别:

ACID规则是摆正多个并行事务能被可靠处理的一组方法策略

  • ALTER SESSION SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
  • ALTER SESSION SET TRANSACTION ISOLATION SERIALIZABLE;

Atomicity:原子性   Consistency:一致性   Isolation:交易之间不被相互作用     Durability:持久性

还可以通过JDBC来设置事务的级别:

复杂的是隔离或可串行化的:确保并行执行相当于对某个顺序的顺序执行。

Connection对象中的方法 void setTransactionIsolation(int level) 可以设置事务级别。其中级别用数字来表示,

这就是并发控制的全部内容。

TRANSACTION_READ_UNCOMMITTED = 1;
TRANSACTION_READ_COMMITTED   = 2;
TRANSACTION_REPEATABLE_READ  = 4;
TRANSACTION_SERIALIZABLE     = 8;

注意:为了保持DB编程的可管理性,DBMS确保串行化是至关重要的,想象一下担心其他查询会妨碍运行的任何查询!

查看当前的事务方法 int getTransactionIsolation() 。

 

5. 事务控制命令

并发控制:

5.1 提交事务

查询被分成许多较小的操作。

在执行使用COMMIT语句可以提交事务,当执行了COMMIT语句后,会确认事务的变化,结束事务,删除保存点,释放锁。当使用COMMIT语句结束事务之后,其他会话将可以查看到事务变化后的新数据。

允许对这些操作进行交错。

5.2 回滚事务

启用并发性

保存点(savepoint):是事务中的一点,用于取消部分事务,当结束事务时,会自动的删除该事务所定义的所有保存点。当执行ROLLBACK时,通过指定保存点可以回退到指定的点。

 

设置保存点:

但如果使用相同的数据,则会出现问题。

sql> Savepoint a;

不能更新(Lost Update)

删除保存点:

不好识别(Dirty Reads)

sql> Release Savepoint a;

不能一致识别(Inconsistent Reads)

回滚部分事务:

 

sql> Rollback To a;

并发控制的目的:

回滚全部事务:

允许通用的并发,但禁止危险的相互作用。

sql> Rollback;

 

6. 数据库锁

Lost update:

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

葡京正网网投 1

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改;加了共享锁的数据对象可以被其他事务读取,但不能修改。

假设有人花了50,并得到了2000,两个事务是同时发生的

6.1 锁分类

语句则被分成很多带顺序的低级操作:

根据保护对象的不同,Oracle数据库锁可分为:

葡京正网网投 2

  • DML lock(data locks,数据锁):用于保护数据的完整性。
  • DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义)。
  • Internal locks 和latches(内部锁与闩):保护内部数据库结构。
  • Distributed locks(分布式锁):用于OPS(并行服务器)中。
  • PCM locks(并行高速缓存管理锁):用于OPS(并行服务器)中。

下面是交错操作:

在Oracle中最主要的锁是DML锁,DML锁的目的在于保证并发情况下的数据完整性。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

葡京正网网投 3

锁出现在数据共享的场合,用来保证数据的一致性。当多个会话同时修改一个表时,需要对数据进行相应的锁定。

这种方式下在账户里增加2000的效率丢失了

锁有“共享锁”、“排它锁”,“共享排它锁”等多种类型,而且每种类型又有“行级锁” (一次锁住一条记录),“页级锁” (一次锁住一页,即数据库中存储记录的最小可分配单元),“表级锁” (锁住整个表)。

 

6.2 共享锁(S锁)

Dirty Reads

可通过lock table in share mode命令添加该S锁。在该锁定模式下,不允许任何用户更新表。但是允许其他用户发出select …from for update命令对表添加RS锁。

当事务读取由另一事务修改的值时,会发生Dirty Reads,但修改不是最终的。

6.3 排他锁(X锁)

葡京正网网投 4

可通过lock table in exclusive mode命令添加X锁。在该锁定模式下,其他用户不能对表进行任何的DML和DDL操作,该表上只能进行查询。

交错操作如下:

6.4 行级共享锁(RS锁)

葡京正网网投 5

通常是通过select … from for update语句添加的,同时该方法也是我们用来手工锁定某些记录的主要方法。比如,当我们在查询某些记录的过程中,不希望其他用户对查询的记录进行更新操作,则可以发出这样的语句。当数据使用完毕以后,直接发出rollback命令将锁定解除。当表上添加了RS锁定以后,不允许其他事务对相同的表添加排他锁,但是允许其他的事务通过DML语句或lock命令锁定相同表里的其他数据行。

返回余额0,即便已经被回滚了

6.5 行级排他锁(RX锁)

 

当进行DML操作时会自动在被更新的表上添加RX锁,或者也可以通过执行lock命令显式的在表上添加RX锁。在该锁定模式下,允许其他的事务通过DML语句修改相同表里的其他数据行,或通过lock命令对相同表添加RX锁定,但是不允许其他事务对相同的表添加排他锁(X锁)。

Inconsistent Reads

6.6 共享行级排他锁(SRX锁)

不一致(不可重复)的读取 发生在在另一事务之间改变时读值多次

通过lock table in share row exclusive mode命令添加SRX锁。该锁定模式比行级排他锁和共享锁的级别都要高,这时不能对相同的表进行DML操作,也不能添加共享锁。

交错操作如下:

上述几种锁模式中,RS锁是限制最少的锁,X锁是限制最多的锁。它们的兼容关系如下:

葡京正网网投 6

葡京正网网投 7

最大余额的账户寻找不到

基本上所有的锁都可以由Oracle内部自动创建和释放,但是其中的DDL和DML锁是可以通过命令进行管理的,命令语法:

浅析Oracle中的事务,数据库设计与事务处理葡京网投哪个正规:。 

LOCK table_name IN 
    [row share][row exclusive][share][share row exclusive][exclusive] MODE 
[NOWAIT];

读/写锁

下图列出产生锁定模式的SQL语句:

目标:

葡京正网网投 8

防止对同一数据的并发访问

当程序对所做的修改进行提交(Commit)或回滚(Rollback)后,锁住的资源便会得到释放,从而允许其他用户进行操作。如果两个事务,分别锁定一部分数据,而都在等待对方释放锁才能完成事务操作,这种情况下就会发生死锁

但要尽量减少对性能的影响

7. 数据库事务实现机制

只在必要时限制以防止问题

几乎所有的数据库管理系统中,事务管理的机制都是通过使用日志文件来实现的,我们来简单介绍一下日志的工作方式。

 

当用户执行一条修改数据库的DML语句时,DBMS自动在日志文件中写一条记录,显示被这条语句影响的每一条记录的两个副本。一个副本显示变化前的记录,另一个副本显示变化后的记录。当日志写完之后,DBMS才实际对磁盘中的记录进行修改。

区分读写操作/访问

如果用户随后执行COMMIT语句,事务结束也被记录在事务日志中。如果用户执行ROLLBACK语句,DBMS检查日志,找出自事务开始以来被修改的记录“以前”的样子,然后使用这些信息恢复它们以前的状态,有效地撤销事务期间对数据库所做的修改。

交错读取操作是无害的。

如果系统出错,系统操作员通常通过运行DBMS提供的特殊恢复程序来复原数据库。恢复程序检查到事务日志末尾,查找故障之前没有被提交的事务。恢复程序回滚没有完全完成的事务,以便仅有被提交的事务反映到数据库中,而故障中正处理的事务被回滚。

交错写入操作会引起问题。

事务日志的使用明显增加了更新数据库的开销。在实际中,主流商用DBMS产品使用的日志技术比上述描述的方案更复杂,用以减小这种开销。此外,事务日志通常被存储在高速磁盘驱动器中,不同于存储数据库的磁盘,以减小磁盘访问竞争。某些个人计算机DBMS产品允许关闭事务日志性能,以提高DBMS的性能。

交错读写操作也会引起问题。

8. 示例

 

银行转帐的例子是最经典的事务示例:

两种锁:

用户把钱从一个银行账号转账至另一个银行账号,需要将资金从一个银行账号中取出,然后再存入另一个银行账号中。理想来说,这两次操作都应该成功。但是,如果有错误发生,则两次操作都应该失败,否则的话,操作之后其中一个账号中的金额将会是错误的,整个操作过程应该是原子性的,两个操作都是一个原子事务操作的一部分。

读锁(又名共享锁)

示例:

写锁(又名专用锁)

葡京正网网投 9

可以有多个读锁或单个写锁

-- 从账户一向账户二转账
DECLARE
  v_money NUMBER(8, 2); -- 转账金额
  v_balance account.balance%TYPE; -- 账户余额
BEGIN
  v_money := &转账金额; -- 输入转账金额
  -- 从账户一减钱  
  UPDATE account SET balance = balance - v_money WHERE id=&转出账户
  RETURNING balance INTO v_balance;
  IF SQL%NOTFOUND THEN
    RAISE_APPLICATION_ERROR(-20001, '没有该账户:'||&转出账户);
  END IF;
  IF v_balance < 0 THEN
    RAISE_APPLICATION_ERROR(-20002, '账户余额不足');
  END IF;

  -- 向账户二加钱
  UPDATE account SET balance = balance + v_money WHERE id=&转入账户;
  IF SQL%NOTFOUND THEN
    RAISE_APPLICATION_ERROR(-20001, '没有该账户:'||&转入账户);
  END IF;

  -- 如果没有异常,则提交事务
  COMMIT;
  DBMS_OUTPUT.PUT_LINE('转账成功');

  EXCEPTION
    WHEN OTHERS THEN 
      ROLLBACK; -- 出现异常则回滚事务
      DBMS_OUTPUT.PUT_LINE('转账失败:');
      DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;

 

葡京正网网投 10

在事务访问数据之前,它必须获取锁,如果不可能,稍后再尝试

 

锁定可以在不同级别下发生:数据库级,表级,页面级别(最常见),行级

原文连接:Oracle数据库之事务

 

数据库级别:只需要单个锁,但不并发

行级:大并发,但需要的锁太多

表和页级锁提供了一个折衷方案

 

多查询事务随时间获取锁,在需要时获得很容易。

但是什么时候释放它们呢?

越快越好并发,但有问题

那么,如果我们释放一个锁,然后又需要它会发生什么?

那么,如果我们释放一个锁,然后需要一个不同的锁会发生什么?

葡京正网网投 11

二相锁定协议

成长阶段:获取锁(无锁释放)  收缩阶段:释放锁(没有获得的锁)也就是在事务结束时释放所有锁

防止有问题的操作交错

葡京正网网投 12

两阶段锁定(带表级锁):

葡京正网网投 13

死锁(Deadlocks)

两个事务可能互相等待释放锁。

  因为两者都在等待,没有一个释放他们的锁。

  也可以发生两个以上的事务,这种僵局被称为僵局。

  两相锁定不能防止死锁

葡京正网网投 14

死锁可以用不同的方式处理:

死锁预防:

  如果发生僵局,就采取行动

  可能不必要中止交易

死锁检测:

   如果发生死锁,只能采取行动

  用于检测死锁的开销

额外的问题:饥饿

为了解决死锁,事务需要中止(如果可能的话重新开始)

相同的事务可能会一再中止(它“饿死”了)。

解决方案:总是中止上次提交的事务

  所有的事务都是时间戳的。

  当中止并重新启动时,保留原始时间戳。

 

死锁预防:

等待-死亡方案:

如果T1需要一个T2持有的锁:

(等待)如果T1大于T2,等待锁定被释放。

(死亡)如果T1较小,中止T1并稍后重启。

 

伤口等待方案:如果T1需要一个T2持有的锁:

(受伤)如果T1大于T2,则中止T2并重新启动。

(等待)如果T1较小,等待锁定被释放。

 

两种方案的共同点:

死锁被解决的了

年轻的过程中止了——没有饥饿

即使没有死锁,事务也可能中止

 

死锁检测:

目标:只有死锁发生时才会中止

 

构造和维护等待图

每个事务都是一个节点。

如果Ti在等待Tj持有的锁,则从TI到TJ的有向边。

如果图包含任何循环,则为死锁。如果检测到循环,则中止一个事务以中断循环 例如:最年轻的交易——没有饥饿。

维护等待图和检测周期是昂贵的

最适合于很少并发事务的数据库,或者当重新启动事务是有问题的(例如中间结果已经返回)

 

死锁解析由DBMS处理,但并非所有的实现都能防止饥饿。,频繁死锁减速处理(DBMS可能需要一些帮助)

谨慎地构造交易可以减少僵局:

  提前锁定(在事务开始时),减少锁定操作交错的机会

  以固定顺序获取所有事务的锁,防止死锁,但对于大的代码库是困难的

在每种情况下,都必须声明所需的锁。

DBMS提供用于获取/释放锁的工具

 

DBMSs还允许禁用/减弱锁定,防止/减少死锁,加快查询速度,但能制造出不可复制的讨厌的bugs

在大多数情况下,这是个坏方法!


频繁类型的死锁:先读取数据,然后更新

葡京正网网投 15

许多DBMS提供更新锁来处理这个问题。

只允许读取数据

不能有多个更新锁(或更新+写锁),防止上述类型的死锁

允许单个更新锁+多个读锁,不阻止读写锁定

必须由用户明确声明,例如

葡京正网网投 16

 

 

数据库恢复

当事务中止时,必须进行更改。

事务被终止可能由于

  用户发出的显式回滚

  死锁、超时或错误

  数据库管理系统崩溃

在DBMS崩溃的情况下,我们需要确保

  所有未提交的事务都会回滚。

  所有已提交事务的更改被保存。

更新通常只在内存中执行,更快,但在DBMS崩溃期间丢失

 

事务日志

所有数据修改都记录在事务日志中。

  存储“前后”和“后”值

  允许改变颠倒

  必须在数据更改之前发生日志记录。(日志没有变化是可以的,没有日志的更改是坏的)

元数据也存储在事务日志中。

  事务的开始/结束(提交或回滚)

  检查点(从内存保存到磁盘的数据),可以识别哪些更新丢失了

当DBMS崩溃时,重新启动它

  读取事务日志

  标识未提交的事务并将它们滚回。

  识别并重新应用已提交事务的丢失更新

dB以一致状态(原子性)开始。

所有承诺的事务持续(持久性)

 

Summary

事务将数据库命令分组为单元

ACID确保DB相互作用是可靠的

交错操作对性能至关重要。

  为了保证隔离,需要进行并发控制

  锁定数据会导致死锁

  解决僵局的协议(DBMS),

  最小化死锁的技术(用户)

使用事务日志的数据库恢

本文由葡京网投哪个正规发布于新葡亰-数据,转载请注明出处:浅析Oracle中的事务,数据库设计与事务处理葡京网投哪个正规:

关键词:

上一篇:创建_Log表及触发器,Log表中_MsSql_脚本之家

下一篇:没有了