mongodb数据库调试问题:‘db object already connecting, open cannot be called multiple times’
在微博小系统的调试过程中:
(1)登入登出可以正常显示,就是在注册的时候网络连接突然停止,但是用户名和密码已经存入数据库中,报错为:undefined is not a function
错误主要指向Use.js中的一句话:mongodb.close();
解决方案:因为mongodb版本高于1.3.0,所以认为mongodb.close()这个函数未定义而当做函数来用,直接把mongodb.close()这句话注释掉则系统可以正常注册运行;
(2)注释掉mongodb.close()以后系统又出现mongodb经常会出现的错误db object already connecting, open cannot be called multiple times’
nodejs是异步线程,无论如何,都要用到db.open(),但是每次打开数据库访问完毕后还得对应关闭书裤裤db.close();
在上一步调试中注释掉关闭数据库,则数据库一直是处于打开状态,数据库还未关闭就在此打开则会出现db object already connecting, open cannot be called multiple times’的错误
此时的解决方案:
a:在数据库在此打开之前直接在前面加上一个mongodb.close()以确保每次数据库打开之前已经关闭数据库,经调试系统正常运行;
b.从open and close 行为改为 open once and reuse anywhere。程序启动的时候db.open一次,每次http请求直接访问数据库,扔掉db.open/db.close这2个多余的操作
原始的open + close方法:
var server_options={};
var db_options={w:-1}; var mongodb = require("mongodb"),
mongoserver = new mongodb.Server('localhost', 27017,server_options ),
db = new mongodb.Db('test', mongoserver, db_options); var http=require('http'); var server=http.createServer(function(req,res){
db.open(function(err,db){
if(err)return console.error(err);
console.log('* mongodb connected');
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
db.close();
});
}) });
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
//http.get('http://localhost:8080',function(res){console.log('request ok')});
//http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
扔掉db.open/db.close这2个循环对应操作的方法,让其最开始就一直处于打开状态
var server_options={'auto_reconnect':true,poolSize:5};
var db_options={w:-1}; var mongodb = require("mongodb"),
mongoserver = new mongodb.Server('localhost', 27017,server_options ),
db = new mongodb.Db('test', mongoserver, db_options); db.open(function(err,db){
if(err)throw err;
console.info('mongodb connected');
});
var http=require('http'); var server=http.createServer(function(req,res){
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
}); });
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
http.get('http://localhost:8080',function(res){console.log('request ok')});
http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
这样改会引入潜在问题:当并发访问>5时,因为同时可用的底层数据库连接只有5,从而导致了阻塞。
实际应用场景中,直接引用db对象并不是一个好主意。默认情况下,db的poolSize=5,意味着并发只有5, 要提高并发的话,把poolSize拉到10? 20? 50? 100? NO,我们需要的是能动态调整连接数的连接池,既能满足高峰期的连接数要求,也能在空闲期释放闲置的连接,而不是象mongodb的内置连接池那样保持固定连接数。怎么办?重新发明轮子吗?不,重用已有的连接池模块generic_pool,代码如下
var http=require('http'),
mongodb = require("mongodb"),
poolModule = require('generic-pool'); var pool = poolModule.Pool({
name : 'mongodb',
create : function(callback) {
var server_options={'auto_reconnect':false,poolSize:1};
var db_options={w:-1};
var mongoserver = new mongodb.Server('localhost', 27017,server_options );
var db=new mongodb.Db('test', mongoserver, db_options);
db.open(function(err,db){
if(err)return callback(err);
callback(null,db);
});
},
destroy : function(db) { db.close(); },
max : 10,//根据应用的可能最高并发数设置
idleTimeoutMillis : 30000,
log : false
}); var server=http.createServer(function(req,res){
pool.acquire(function(err, db) {
if (err) {
res.statusCode=500;
res.end(JSON.stringify(err,null,2));
} else {
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
pool.release(db);
});
}
});
});
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
http.get('http://localhost:8080',function(res){console.log('request ok')});
http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
c.对于mongodb数据库有一个问题:刷新得太快,或者多个用户同时访问数据库,数据库没来得及关闭,db object already connecting, open cannot be called multiple times这个错误就会出现
我们如果换成使用mongoose就不会出现这错误,因为对于mongoose而言,一旦连接好数据库,db就会处于open状态,不存在访问时要打开,然后又要关闭的规则,
这是用mongodb的操作方法:
User.get = function get(username, callback) {
mongodb.open(function(err, db) {
if (err) {
return callback(err);
}
//读取 users 集合
db.collection('users', function(err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
//查找 name 属性为 username 的文档
collection.findOne({name: username}, function(err, doc) {
mongodb.close();
if (doc) callback (err, doc);
else callback (err, null);
});
});
});
};
这是用mongoose的操作方法
User.get = function get(username, callback) {
users.findOne({name:username}, function(err, doc){
if (err) {
return callback(err, null);
}
return callback(err, doc);
});
};
以上a.b.c则为解决db object already connecting, open cannot be called multiple times’问题的三种方案总结
mongodb数据库调试问题:‘db object already connecting, open cannot be called multiple times’的更多相关文章
- nodejs:注册登录session出错以及连接Mongodb数据库时Error connecting to database解决方案
(1)nodejs:注册登录session出错 解决办法: 在app.js 中将var MongoStore = require(connect-mongo')改为var MongoStore = ...
- mongoDB数据库插入数据时报错:db.collection is not a function
nodejs连接mongodb插入数据时,发现mongoDB报错:db.collection is not a function.解决方法: 1.npm下载mongodb2.x.x版本替换3.x.x ...
- node.js连接MongoDB数据库,db.collection is not a function完美解决
解决方法一. mongodb数据库版本回退: 这个错误是出在mongodb的库中,在nodejs里的写法和命令行中的写法不一样,3.0的api已经更新和以前的版本不不一样,我们在npm中没指定版本号的 ...
- MongoDB数据库(一):基本操作
1.NoSQL的概念 "NoSQL"一词最早于1998年被用于一个轻量级的关系数据库的名字 随着web2.0的快速发展,NoSQL概念在2009年被提了出来 NoSQL最常见的解释 ...
- python学习笔记——mongodb数据库
1 概述 1.1 文件管理阶段 优点:可以长期保存 能存储大量数据 缺点:没有结构化的组织 查找不方便 数据容易冗余 1.2 数据库管理阶段 有文件存储的优点,同时解决了文件存储的问题 缺点 : 操作 ...
- Python全栈 MongoDB 数据库(概念、安装、创建数据)
什么是关系型数据库? 是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据, 同时也是一个被组织成一组拥有正式描述性的表格( ...
- MongoDB 数据库的学习与使用
MongoDB 数据库 一.MongoDB 简介(了解) MongoDB 数据库是一种 NOSQL 数据库,NOSQL 数据库不是这几年才有的,从数据库的初期发展就以及存在了 NOSQL 数据库. ...
- python操作mongodb数据库
一.MongoDB 数据库操作 连接数据库 import pymongo conn = pymongo.Connection() # 连接本机数据库 conn = pymongo.Connection ...
- mongoDB数据库
1.mongoDB简介:mongoDB 为非关系数据库,集合(collection)关系数据库中的表,中存储的为json结构的文档,集合中的每一条记录都可以结构不同, 但必须都有_id字段(mongo ...
随机推荐
- 【转】 LESS CSS 框架简介
简介 CSS(层叠样式表)是一门历史悠久的标记性语言,同 HTML 一道,被广泛应用于万维网(World Wide Web)中.HTML 主要负责文档结构的定义,CSS 负责文档表现形式或样式的定义. ...
- 打造 通用的 支持多数据库 操作的 DBHelper
闲来无事,写一个通用的直持多数据库的DBHelper,支持单连接批量执行SQL 因为用了TransactionScope所以请引用System.TransactionScope.dll 代码尚未测试, ...
- SharePoint解决方案由VS2010升级到VS2013部署页面报错
“/”应用程序中的服务器错误.----------------------------------------文件“/_CONTROLTEMPLATES/....../XXXUserControl.a ...
- c++中冒号(:)和双冒号(::)的用法
1.冒号(:)用法 (1)表示机构内位域的定义(即该变量占几个bit空间) typedef struct _XXX{ unsigned ; unsigned char c; } ; XXX (2)构造 ...
- 第四课 Grid Control实验 GC OMS安装(第二台机器部署)
2.GC OMS安装(第二台机器部署) 1. 配置图形化 [oracle@ocm2 ~]$ xhost + access control disabled, clients can connect f ...
- OC中给我们提供的一个技术:谓词(NSPredicate).note
OC中给我们提供的一个技术:谓词(NSPredicate)OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到 ...
- JAVA 年轻代收集器 第九节
JAVA 年轻代收集器 第九节 继续上一章所讲的,STW即GC时候的停顿时间,他会暂停我们程序中的所有线程.如果STW所用的时间长而且次数多的话,那么我们整个系统稳定性以及可用性将大大降低. 因此我 ...
- 用一条sql查出总长和状态为2是长度
查询同一张表里同一个字段值的和以及状态是2(或1)时,该字段值的和
- VS的Release模式配置技巧
环境:如果要将bin\release目录作为我们产品的发布目录或者产品来源目录,那么release目录中就只能有产品需要用到的东西,但是以VS默认的配置编译的话会生成比较讨厌的.pdb,.vshost ...
- OC语法10——@protocol协议,
参考资料:博客 @protocol,协议: OC中protocol的含义和Java中接口的含义是一样的,它们的作用都是为了定义一组方法规范. 实现此协议的类里的方法,必须按照此协议里定义的方法规范来. ...