博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于redis实现的锁(用于控制nodejs的并发)
阅读量:7072 次
发布时间:2019-06-28

本文共 2555 字,大约阅读时间需要 8 分钟。

场景:使用node+mongo搭建web应用时,常常遇到并发问题导致创建一条数据的时候会同时创建多条。

通过redis set 方法 配合 ‘NX’ 选项即可实现锁机制。

主要的方法有三个:

lock(加锁)

unlock(解锁)

extend(更改锁过期时间)

Redlock.prototype.lock = function(resource,ttl,callback){  var self = this;  var _val = _random();  return new Promise(function(resolve, reject) {    var lock = new Lock(self, resource, _val);    self.client.SET(resource,_val,'EX',ttl,'NX',function(err,data){      if(!err && data === 'OK'){        return resolve(lock);      }else{        var err = err || 'resource: '+resource+' is locked.';        self.emit('lockError', err);        return reject(err);      }    })  }).asCallback(callback);}

Redlock.prototype.unlock = function(lock,callback){  var self = this;  return new Promise(function(resolve, reject) {    if(typeof lock !== 'object') return reject('unlockError:lock is not object.');    self.client.GET(lock.resource,function(err,data){      if(!err && data === lock.value){        self.client.DEL(lock.resource,function(err){          if(err){            self.emit('unlockError',err);            return reject('unlockError:'+err);          }else{            return resolve(lock);          }             })      }else{        self.emit('unlockError',err || 'resource:' + lock.resource + ' unable to unlock.')        return reject('unlockError:' + err || ('resource:' + lock.resource + ' unable to unlock.'));      }    })  }).asCallback(callback);}

Redlock.prototype.extend = function(lock,ttl,callback){  var self = this;  return new Promise(function(resolve, reject){    if(typeof lock !== 'object') return reject('unlockError:lock is not object.');    self.client.GET(lock.resource,function(err,data){      if(!err && data === lock.value){        self.client.expire(lock.resource,ttl,function(err,data){          if(!err && data === 1){            return resolve(lock);          }else{            self.emit('extendError', err);            return reject('extendError:'+err);          }                  });      }else{        self.emit('extendError', err);        return reject('extendError:'+err);      }    })  }).asCallback(callback);}

用法

var client = require('redis').createClient('port','host');var redlock = new RedLock(client);var lock;`callback`://lockredlock.lock('test-resource-lock',3,function(err,lockInstance){  lock = lockInstance;  done(err);});//unlockredlock.unlock(lock,function(err,data){  done(err);});`promise`:redlock.lock('test-resource-lock-promise',3).done(  function(lock){    //todo    redlock.unlock(lock);  },  function(){  })

PS:支持callback and promise.

实现比较简单,100行内,有兴趣的可以在 查看源码

转载地址:http://vuell.baihongyu.com/

你可能感兴趣的文章
Homebrew 1.9发布,将支持Linux与Windows 10
查看>>
Spring Web Services 3.0.4.RELEASE和2.4.3.RELEASE发布
查看>>
Kotlin 1.3带来稳定的协程、合约及其他
查看>>
微软公布Visual Studio 2015产品线,可直接生成Linux二进制程序
查看>>
敏捷心态到底是什么?
查看>>
矩阵:如何使用矩阵操作进行 PageRank 计算?
查看>>
腾讯云10亿扶持小程序:3元套餐可能免费
查看>>
专访《Haskell函数式编程入门》作者张淞:浅谈Haskell的优点与启发
查看>>
eval()的使用和兼容性问题
查看>>
KMP模式匹配算法(二) next数组
查看>>
连连支付注意事项
查看>>
【面试系列】番外:关于糯米面试
查看>>
angular组件(ngKeybordSelect)-通过键盘实现多选
查看>>
C — 用单向循环链表完成“类约瑟夫环”问题
查看>>
整型字面量的那些事
查看>>
Fastreport.Net用户手册(二):报表设计器
查看>>
精益 React 学习指南 (Lean React)- 1.6 Flux
查看>>
【译】UICollectionView 轻松重排
查看>>
Vue.js前后端通用组件开发心得-菜鸟篇
查看>>
快速制作机房3D效果图教程
查看>>