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 ...
随机推荐
- CSS3属性text-overflow(省略符)实战开发详解
先看一下效果: 好了,看完了效果,现在正式开始今天的开发旅程吧! 首先我们先创建html页面,代码如下所示(红色文字即是我们Demo的主要内容): <!DOCTYPE html> ...
- sessionStorage和localStorage之间的差别
<!DOCTYPE html><html> <head lang="en"> <meta charset="utf-8" ...
- spring加载jar包中多个配置文件
转自:http://www.cnblogs.com/GarfieldTom/p/3723915.html <import resource="classpath*:applicatio ...
- 在SQL Server 2008 中使用SQL脚本创建登录用户并授权
到处都使用超级用户sa显然是不安全的,因此有创建用户并让其只能访问某个数据库的必要.当然可以使用SQL Server自带的图形界面向导,但是太难用用了!有时候代码比较直接,比如这里: --使用已经创建 ...
- [Script]EBS里查看模块的版本、文件的版本信息【Z】
系统版本信息 装了哪些模块,以及版本信息 select 'Current Application Release: '||ver||' ('||bug||')' "Description&q ...
- poj1995-快速幂取模
#include<iostream> #define LL long long using namespace std; //快速幂算法 LL pow(LL a,LL b,int m){ ...
- win32 控件的创建和消息响应
1. 控件的创建 控件的创建和窗口创建是一样的,例如: ,,,, hWnd,(HMENU)IDB_BUTTON01,hInst,NULL); 是一个按钮的创建,其中hWnd是窗口句柄,hInst是应用 ...
- BZOJ 1396: 识别子串( 后缀数组 + 线段树 )
这道题各位大神好像都是用后缀自动机做的?.....蒟蒻就秀秀智商写一写后缀数组解法..... 求出Height数组后, 我们枚举每一位当做子串的开头. 如上图(x, y是height值), Heigh ...
- JRainbow开发进度
最新版本下载 http://pan.baidu.com/s/1c0GcDMg&third=15 相关信息 JRainbow的简单介绍:http://blog.csdn.net/jrainbow ...
- 从零开始PHP学习 - 第四天
写这个系列文章主要是为了督促自己 每天定时 定量消化一些知识! 同时也为了让需要的人 学到点啥~! 本人技术实在不高!本文中可能会有错误!希望大家发现后能提醒一下我和大家! 偷偷说下 本教程最后的目 ...