您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 招聘面试 > 用锁和最后心跳时间机制解决并发访问问题
用锁和最后心跳时间机制解决并发访问问题上个月遇到这么一个问题:OA系统流程当中允许配置一个环节由多个人同时办理,他们共享同一个物理文件。这样一来就有可能造成一系列的并发问题,一是文件访问的并发,二是IO操作的并发,三是流程操作的并发。第三个问题不属于本文讨论范围,第二个问题C#自带文件IO的共享机制,关于第一个问题,采用了如下方案来解决:一栋大楼里只有一个厕所,你要进去的时候,肯定要根据门锁的情况判断有没有人在里面,如果锁了你就进不去了,然后等那个人出来了,锁也开,你就可以进去了,然后自己再锁上。显然这种实现要用数据库记录文件是不是被占用了,就是一个字段,进去的时候要写库,出来的时候要清库。如果想知道谁在里面,可以问一嗓子,或者干脆规定进去的人要在门上挂个牌子,当然,也可以允许门外的人以“某种权限“进到有人的厕所里,比如只读……呃……这种实现方式需要在数据库里记录是谁在厕所里写数据,也就是他的id和名字分别是什么。那么新的问题就来了,如果说一个人正在蹲坑,突然断电了,数据库里的锁定记录是不会消失的,那外面的人岂不是永远进不来了吗?为了解决这个问题,可以让厕所里的人每间隔5分钟修改一下数据库记录当前时间来证明他还活着,外面的人想进去的时候先看看他是不是掉到坑里已经超过30分钟了,如果超了,就可以强行破门而入了!可以把文件主键ID,访问人的ID、姓名和最后更新时间放在一张数据表里,定时更新时间和超时时间可以写在配置。这套方案可以应对一些访问权限之类的问题,可以弄一个通用锁定控制模块,问题是,对于高并发下几十毫秒就完成的操作,加锁解锁对数据库压力太大,待考虑其他策略。最近在琢磨并发操作控制的问题,在此小小总结一下关于状态保持机制和并发解决方案,如有问题希望大家留言指正。并发问题分为几类:1.一个办理页面仅允许一个人进,第二个人再点就提示已经被别人访问,难点在于如何解决用户非法退出时放锁。2.一个人“签出”后另一个人无法办理。(这是情景1的简化版)3.多个人同时点“提交”按钮,但是系统应该只允许第一个人成功,后面的人都应该提交失败。4.一个人更新了表单的内容到数据库,另一个人w3wp进程的用户刷新后依旧读缓存而没读取数据库,缓存不同步。情景1和2已经在我另一篇帖子里解决了,这里主要讨论情景3和4的解决方案.对于这种提交操作,大体来讲可以把并发控制的执行流程分为“判锁-上锁-办事-解锁”四个阶段,“锁”是一个表,可以是哈希表,也可以是数据库表。对于提交/保存这样的情景,“办事”阶段仅仅是一个十毫秒级的简单操作,那么放在数据库里显然不妥,不仅严重增大了各方的压力,而且还存在延迟问题,不保证并发安全。接下来分析一下可能能够应用在并发控制当中的几种状态保持机制:1.Session是一种会话相关的状态保存方式,每当浏览器去访问w3wp进程请求页面时,都会在本地生成一个写有SessionId的Cookie,浏览器负责将SessionId加到Http请求报文当中,每新开一个浏览器进程SessionId都不同。在w3wp进程内(或是状态服务当中)每个SessionId对应一张KeyValue哈希表,也就是说一个浏览器进程是读不到另一个浏览器进程写的同名Session的,因为它和会话相关,所以显然不能用作并发控制。2.Application是一种“进程内”哈希表,问题就出在于它是和进程相关的,在多w3wp进程的情况下进程间不能共享Application,也难怪它起了这么个名字,于是它也不能拿来控制并发。3.Cache数据缓存,广泛应用在减少数据库访问压力上,但是目前没找到接口能把它写到进程外,它和Application一样同样存在多w3wp进程的问题,w3wp进程之间是不共享缓存的。如果不能用数据库,那么通过上面的分析,唯一要解决的问题就是这个可以跨w3wp进程的哈希表到底放在哪才能共用。我们先来解决多w3wp进程下情景4的问题。既然是多进程,显然每个进程都有一个id,于是我们可以在Application_Start的时候给每个进程创建一个名为进程id的文件夹,假设A和B同时通过两个进程查看一个表单数据,A提交了表单修改到数据库,数据库写入成功后,可以在B的文件夹下写一个名为Guid的文件,文件里写着表单的主键id,这是对提交过程的修改。对于读取过程,B在读取缓存之前,先去遍历自己的文件夹,如果发现有A写进去的文件,则直接清缓存读库,然后删了文件。上面的方案通过文件的方式实现了对数据修改的“通知”来使多进程间的缓存“伪同步”,但是硬盘IO毕竟有性能损耗,而且仔细分析一下,由于网络延迟,两个人在“判锁”的时候会同时成功进入后面的逻辑,有很严重的安全隐患。最后想到的办法就是用Memcached做分布式缓存了。评论#1楼2012-07-2700:11JunHwong需要那么麻烦吗?只需要在表中冗余一个时间戳不就行了吗.
本文标题:用锁和最后心跳时间机制解决并发访问问题
链接地址:https://www.777doc.com/doc-2203661 .html