资源供给:并发性控制和锁之三

     简单案例描述:
           某运营商的账务系统在某时刻出现业务系统性能下降,简单检查为大量的TX锁等待,同时发现smon在进行大型事务回滚。该业务锁等待的原因非常简单,手工处理的批量update操作意外被中止,引起系统回滚。回滚操作依赖于smon,其回滚的速度会非常缓慢。在这种情况下只能等待回滚完成,或者重新启动数据库加速回滚。

oltp业务和批处理业务
     oltp业务和批处理业务天生具有比较大的冲突,除了在操作系统资源消耗的争夺之外,锁冲突是oltp和批处理混合业务面临的最主要问题。批处理业务在更新的时候典型的会进行大量记录的锁定,并且为了加快处理,锁持有时间会相对时间比较长。oltp和批处理其系统设计初衷截然不同,导致在混合处理的时候往往会遇到严重的冲突问题。oltp的任务是在可接受的响应时间范畴之内尽可能的降低资源消耗和锁持有时间。而批处理则是尽可能的以资源独占的方式来完成业务处理,尽可能的消耗完所有的资源,尽可能长的持有锁以节约上下文切换增加运行效率。
     大家自然可以看到,批处理业务在oltp高峰期运行几乎必然会严重影响oltp系统的并发能力。系统设计和开发人员在面临混合业务的时候必须考虑资源消耗和锁定问题,也就是要像考虑oltp一样来考虑批处理业务:在可接受的响应时间范畴之内,尽可能的降低资源消耗和降低锁持有时间。降低锁持有时间的最简单措施为:降低批处理提交的记录数,从而减少锁定数量,降低锁持有时间。

锁等待和回滚(批处理失败)
     混合业务处理或者单纯批处理业务的一个重大风险就是批处理业务失败。当设计的事务处理记录过于庞大的时候,比如几百万甚至几千万条处理记录进行一次提交,其业务处理意外失败成本将是无法承受的。意外失败的批处理业务将由smon进程来进行回滚,而smon承担着众多的工作,他只能用一部分时间来进行回滚处理,从而导致回滚速度会非常慢。从业务系统的健康运行考虑,设计者需要考虑牺牲部分性能以获取可靠性保障,避免大型批处理业务失败导致不可承受的损失。事实上,我们在实践案例中见到过太多的大型事务意外失败回滚导致的全体业务系统瘫痪,软件设计和开发者必须注意控制事务规模,使其处于可以接收的失败回滚范畴,特别当你的批处理需要oltp进行混合处理的时候,要进一步降低事务处理规模,使其失败回滚不至于对于oltp系统造成长时间的业务延迟影响。

锁等待和死锁
     当两个以上的session构成相互等待对方的锁释放的时候,就构成了死锁。幸运的是,Oracle有比较强大的死锁检测机制,可以快速的发现死锁,并中断其中一个操作,使另一个进行。在业务处理的时候,开发者需要注意,Oracle死锁处理仅仅中断引起死锁的操作,不会进行事务回滚,必须在设计的时候对于死锁失败进行回滚以完成事务一致性。
     如何检查死锁,这类文章网上很多,大家搜索一下处理就可以了。
     如何避免死锁?
     死锁,不是Oracle错误,是一个典型的应用错误(如果表现为自己锁自己,Oracle bug)。最典型的导致死锁的原因为处理顺序错误,类似的业务处理却采用不同的处理顺序导致,往往是不同的程序员由于缺乏共用的业务规则导致。比如A程序员处理为:First Update A row,Then update B row,而B程序员处理相同的业务或者类似的业务处理为:First Update B row,Then Update A Row。一旦这两段运行代码在同一时间点相遇的时候,大家一看就知道,死锁了。
     死锁,不仅仅是TX锁之间的相互等待,从广义上来说,包含任何资源的事务之间相互等待。
     比如:
     A Wait TX Lock holded by B
     B Wait Library cache Lock(x) holded by A

    A Wait TX Lock Holded by B
    B Wait ITL TX Lock holded by A

   A Wait TX Lock Holded By B
   B Wait TM Lock holded By A

有时候,我们需要对于对于表格进行锁定,select for update的锁定效率又太低,成本太高。这个时候,Oracle提供了LOCK TABLE语句来进行表格级别的锁定操作。
LOCK Table 和 锁
    具体的lock table的相关说明不展开说明,大家查看相关文档即可。对于lock table,大家需要知道一点,Lock Table实现了表格锁,表格锁具有比较行锁更高的效率,更低的成本,当然并发性比较行锁要差很多。

自我定义的锁
   有时候我们需要实现对于某张表格或者某些业务的串行性,Oracle数据库也提供了这方面的能力。dbms_lock包实现了定制的串行访问能力,比如说我们需要对于某张表格A在任何时候要求实现串行化,一种方式是处理之间用lock Table,也许更好的处理方式为使用dbms_lock,生成一个手动定义的锁。处理表格之外,dbms_lock提供了lock table所不具备的能力,实现任何业务处理的串行化。我们只要在需要串行化的业务之前调用dbms_lock进行加速,在完成业务处理之后通过release或者提交事务释放锁。具体的dbms_lock的用法参见相关文档即可。


   


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/92650/viewspace-1061742/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/92650/viewspace-1061742/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值