`
阅读更多
数据库事务:

事务:逻辑工作单元,包含1至多条语句,要么全部成功,要么全部失败,
      以commit结尾持久化更改或以rollback撤销操作

ACID 属性:

Atomic(原子性):
    整个事务作为同一个单元要么全部成功要么全部失败。
Consistency(一致性):
   事务中的操作保证数据库中的数据不会出现逻辑上不一致的情况,一致性一般会隐含的包括在其他属性之中。
Isolition(隔离性):
    事务允许多个用户对统一数据进行那个并发访问,而不破坏数据的正确性和完整性。
    同时,并行事务的修改必须与其他并行事务相互独立。由事务的锁来控制
Durabliity(持久性)
    事务处理后,事务处理结果必须能够得到固化。


     事务是多用户数据库和并发计划的基石。一旦一个事务提交成功,这个事务引起的变化将会变成
永久的,对其他事务是可见的。虽然很多事务执行时间很短,但是在事务提交成功前,事务引起的变化对
其他事务是无效的。所以每个事务必须隔离起来互不干涉(for 数据完整性)。实现这个的机制是锁。

锁:
  1.write lock|exclusive lock
        在事务执行过程中,排他锁被获取和应用,排他锁在commit||rollback执行是释放。排它锁同时只能被一个
    用户获取,所以同时只有一个用户修改
  2.read lock|shared lock
     shared lock 可以同时被任意多的用户获取用来检索数据。
     被加了共享说的数据在这个事务结束前不能加排他锁。其他数据智能读取数据不能修改。
     oracle使用共享锁的情况是 select ... for update 语句,其它情况没有共享锁
     ---reference other:
     共享锁(S锁)又称读锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加
    S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何
    修改。
      排他锁(X锁)又称写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A
    加任何锁,直到T释放A上的锁。这保证了其他事务在T释放A上的锁之前不能再读取和修改A



并发和竞争
      并发越多,锁之间的冲突就会有多,竞争就越多,性能就会下降。oracle使用multiversion read concurrency
      scheme可以大大降低这种竞争。

数据完整性问题:
      1.Lost updates
          两个修改对同一个数据进行修改,a会覆盖b的修改数据(排他锁设计为了解决这个问题)
      2.Dirty reads
         数据库允许一个事务读取被另一事务修改的数据,但是这个事务所做的修改还为提交进行持久化,
      这些修改可能会被回滚,所以这个数据读取的事务就是不正确的。很多数据库允许脏读以避免排它锁的竞争。
      3.Nonrepeatable reads
          其他事务修改数据的结果。一个事务特定的条件进行查询数据。在这个事务结束前,查询结果返回后,
      另一个事务修改了数据,导致这些数据不再满足原来的查询条件,如果这个条件查询在执行一次,结果就不同。
      4.Phantom reads 幻读
         一个事务进行查询,在查询结果返回而这个事务结束前,另一事务插入一条新数据也符合前面的查询结果,这是
      事务要根据查询结果尽心相应的修改就不准确 了。


      Serialization 串行化


      oracle多用户并发控制:multiversion read consistency(mvrc)
          mvrc确保用户看到的他所需要的数据始终如一。如果另一个用户修改了这些数据,在这个用查询执行的过
      程中。oracle会维护一个这个数据在查询开始时的数据版本,如果在查询开始的时候,这些修改数据的事务为提交
      ,oracle会确保忽视这些事务的修改。查询结果只会在查询开始时,已经提交的事务的基础上找。
        1.oralce读数据不加任何锁
        2.用户会得到一个完整的数据快照,不受其它事务干扰


oracle 隔离级别:
   1.read commit:
      statement level serialization
      每一个语句,在语句开始时,会获取一个此刻的数据快照。一个事务有多条语句,如果语句之间存在其它完成的事务,
      这可能引起不可持续读和幻读。oracle的默认隔离级别

   2.serializable
      transaction level:一个事务中的语句共享同一个数据快照(在事务开始时存在的数据)
   3.read-only
  




Oracle Concurrency Features 并发特点
 
  1.Rollback segments 回滚片段
     回滚片段目的是为了事务回滚到事务前数据信息。当事务开始修改数据块时,首先会把这个时刻的数据快照
  写入到rollback segment。rollback segment中的信息是回滚事务和多版本读取数据一致性的前提。
     回滚片段不同于重做日志。重做日志是记录数据库所有的事务,当系统突然宕机的时候恢复数据库,
     while the rollback segment provides rollback for transactions and read consistency。
     回滚片段数据块缓存在系统全局区,就项表和索引一样。当rollback segment长时间不用时,可能从缓存中写到
     磁盘。
  2.System Change Number (SCN)
      为了保证数据的完整性,保存数据库操作的顺序是至关重要的。oracle必须保证事务在时间上的执行顺序。
   oracle实现这个的机制是SCN.
      SCN是事件发生顺序的逻辑时间戳,oracle使用在重做日志中存储的SCN信息在原始数据上从新执行事务,以便
   正确的进行重做。oracle同时也根据SCN决定什么时候清除不在需要的rollback segement信息。
  3.Locks in data blocks
       数据库必须有一种方式来确定特定行是否被锁定。大部分的数据库在内存中存储着一个锁的列表,这个列表被
    一个锁管理进程维护。oracle将锁存放在具体的行信息存储的数据块区。对oracle数据库来说数据块是最小的可以从磁盘中
    读取的数据单元,所以当行上有请求的时候,数据块被读取,块中存储的锁也便有效。行所对应的数据块的头部存有SCN信息。
       oracle的这3个特点实现了multiversion read consistency(mvrc)。
       select读取数据的时候:读取数据块,从块的头部信息获取SCN和当前SCN进行比较,如果当前SCN<块的SCN,那么就说明在
       select开始后块的数据被修改过,再根据SCN找到其对应的事务的rollback segement获取旧的数据块值,递归的执行上面的
       操作直到SCN小于当前的SCN。


oarcle并发操作控制过程 例子?
   
    1.oracle 写并发 (A,B修改同一行)
        (1).A发送一个update sql
(2).数据库获取这个sql的SCN,读取目标行所对应的数据块。
(3).数据库在这些数据块上加上锁标记
(4).数据库copy当前的数据快照到A事务的回滚片段中,完成后,数据库修改读取的缓存数据块中的数据(根据sql语句)
(5).数据库更新修改到A事务的回滚片段和数据库块中。
(6).B发送一个同样的update sql
(7).同2
(8).数据库从读取的数据块信息的header中发现,目标行上存在lock。下面的执行根据隔离级别执行:
    如果B的隔离级别是READ COMMITTED,等待阻塞事务的执行完毕;如果B的隔离级别是SERIALIZABLE,error return。
(9).A提交事务。数据库执行相应的操作,发送确认信息给A
(10).如果B事务的隔离级别是READ COMMITED,B开始执行......

    2.oracle 读、写并发
        (1).Client A通过网络给数据库服务器发送一个select sql
        (2).服务器获取这个sql的SCN,开始读取这个查询所需要的数据,对这个查询读取的每个数据块,服务器
    都会比较这个select sql的SCN和数据块所在行上的任何未提交的事务的SCNS.如果服务器发现了一个未提交
    事务的SCN号晚于select的SCN,那么数据库会使用这个事务回滚片段中的数据作为这个数据块的当前快照(select
    语句开始时间)
(3).Client B向服务器发送一个update sql影响某一行目前还未被client A的select sql所读取。服务器生成这个
    事务的SCN,开始操作
(4).Client B提交了修改。服务器完成了操作,写入了修改行数据到对应的数据块包含SCN号。
(5).Client A 查询读取到刚被B修改的行。发现了该行对应的数据块被SCN晚于select语句的SCN的事务修改过。
    服务器查询这个数据块的头部信息(存有A事务的回滚片段,存有A事务开始时的数据快照),仍旧读取A事务开始时
    的数据。B事务的修改被A忽略。



oracle悲观锁和乐观锁:
    悲观锁:悲观的认为从取出数据到提交修改的过程中,别的用户会对该数据进行修改,会引发更新丢失,所以需要在取数据的
            时候锁定数据行。

    oracle使用select ...for update 锁定行,然后进行update...
    乐观锁:乐观的认为从取出数据到提交修改,别的用户不会修改该数据,不需要在取出是就加锁。不依赖数据库的事务机制,不会
            锁住任何东西,但是为了提交是能够判断是否有用户修改该数据,需要加时间戳或版本字段用来提交事务的时候判断是否
    有事务修改数据,是否可以提交还是整个回滚。

1
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics