PHP-在大并发的情况下如何避免多人同时编辑一篇文章?
在大并发的情况下,如何避免多人同时编辑一篇文章?MySQL数据表是MyISAM引擎。在数据库里加字段标识效率有点低,每次都要先查询数据库再判断,有没有什么更好的的方法?有一种情况是,可能有某人正在编辑这篇文章,但是没有提交(比如:直接关闭浏览器),有可能会一直占用着这个资源锁的情况也需要考虑。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这个问题遇到过,当时用在一个php项目中 mysql的数据库插入之前锁表,这样可以让插入操作排队LOCK TABLES table_name WRITE
操作完成解锁
UNLOCK TABLES
是不是可以这样:
建立一个新的table若某用户对某文章做了编辑,则将该文章的id与用户关联
其它用户在刷新文章列表时做联合查询,这样其它用户就看不到这个正在编辑的文章了,在文章编辑完成后在删除掉该关联,因为这个table的数据结构较为单一,且相对独立(若编辑和删除操作不是同一个用户完成,最好也用这个table限制下)效率上应该不会有很大影响。
对数据库只有两个操作
开始编辑时加一条记录;
完成编辑是删一条记录;
其它用户通过联合查询可以不显示这这正在编辑的文章。
(方法同加字段,我只是考虑到主表可能关联过多,数据量效大,操作恐影响效率,所以建了个新表,个人思路,有错还请指正批评)
同时多人编辑出现的错误是后编辑的人会覆盖前面编辑的人的作品。而如果真的要深挖掘这个需求,其实除了锁定这篇文章(不排除用户恶意将文章锁定,让其他所有人都无法编辑),还有一种比较牛的方法就是用操作转换(Operational Transformation,简称OT)实现多个人同时协同编辑一份文档。大名鼎鼎的Google Docs和Etherpad所采用的实时协同的核心原理就是OT技术。通过OT来协同编辑的文档既可以是纯文本的,Markdown,也可以是富媒体的,甚至可以是同时画一幅图片。
为了实现多人同时编辑,一定要尽可能地降低延迟,所以使用websockets进行双向传输是必不可少的,所以一般来讲,除了使用php做网站基础以外,还需要node.js做文本同步修改服务器。这里有三种方案可以实现(每一个都有在线demo,供大家自己实验,可以打开多个标签进行编辑):
使用云端服务器托管文本数据,如以Firebase为数据后台的Firepad模块
使用包括前后端的成熟的OT框架,例如Sharejs
使用更为基础的OT.js,其中Firepad就是将OT.js结合了Firebase的后台实现的
回到原先的问题,实时协同编辑自然有其适合的场景,比如wiki或者文档协作机制。
当编辑一遍文章事,将这个文章id记录在memcache中(过期时间比如5分钟),每次点击修改功能先判断能不能从memcache中取到值,能取到值的话,点击编辑功能时,提示该文章正在被编辑。
在文章编辑页面,加ajax定时请求(<5分钟),去延长该文章id在memcache中的过期时间。文章编辑后提交,删除改文章id在memcache中的值。
同时在编辑页面加入 onbeforeunload 事件 去删除当前文章id在memcache中的值。(这样也只能避免一部分),但是memcache中的过期时间是 5 分钟,所以一直占用着这个资源锁的情况最多也就5分钟。当然时间只是举例。希望大家分享更好的解决方法。
你可以用innodb试试,利用事务,比如那个字段叫isedit,0代表没有编辑,1代表正在编辑,你更新数据时sql为update abc set content='xxxxxxxx' where isedit=0;如果isedit为1这条sql就不通过,数据就回滚了。