.net高并发实时系统,应该用什么办法来解决数据库死锁。
高并发实时,结算系统,类似银行的系统,像这种系统,当并发量大时,很容易出现死锁,即便对sql 和程序进行最大优化,并发很大时,也出现死锁。除了升级硬件和负载均衡,有没有别的什么办法解决。
------解决方案--------------------
软件设计是循着业务逻辑而深入的,而不是简单地增删改查一下数据库。比如(举个最简单形式的例子)你发送一个手机短信给另外一个人,首先从业务上说这个信息根本无需落地,无需存储。这个时候并不是纠结于这些消息会有万一丢失的情形。而当系统完全运行之后,如果需要保留上行短信消息并对系统某个点的代码进行重构的时候,那么最终用户可能才会在发送消息一分钟以后从存储介质上看到保存的消息(也就是说,并不需要设计为首先事实地保存数据记录,比如我们可以通过MSMQ或者其它SOA方法把消息传给其它系统去排队处理)。
而我们看看所谓的“数据库脑袋”是如何设计软件的。他往往是把这个业务逻辑先入为主地描述为“一个程序把消息写入MySQL数据库,同时系统进行审查和计费等工作,另外一个程序从数据库中去查询消息”这种描述。然后他就会再想当然地给出“系统同时并发有1万个发送任务”这个约束。最后任何高性能业务设计问题,到他那里就变成了上万个终端同时增删读写一个关系数据库的问题,而跟业务逻辑设计没有关系了!
遇到这样的开发习惯,我们只能无奈了。
------解决方案--------------------从然间机理角度讲,锁死的原因肯定有两把锁,各自进程所了不同的资源,进行操作,而又试图访问对方资源,由于访问对方资源时,对方锁定资源只能等待,如果双方都一直等待,就会造成死锁。因此看,死锁问题并不一定只发生在数据库中,也可能有线程死锁。
对于数据库死锁,一般数据库本身都有牺牲机制,可以放弃一个操作,因此倒是好处理一些,只要能够捕获到异常并能够处理即可,但由于很多应用开发商结构化做的不很好,往往是没有很好处理异常,才会导致软件的大量问题。对于新手,往往连警告都不带看的,更甭提异常的预防处理了。
另外一点是,很多人编程很不注意,往往将begintransaction放到交互的开始中,交互完成时再committransaction, 而不是完成处理时设置事务,其他链接不死才怪,这只能说是人祸,不能怪数据库。
倒是线程死锁需要编程时手工处理,很多人往往没有怎么注意它。
------解决方案--------------------