用python自定义实现db2的连接池

手动迁移原创博客,原文发表在http://www.cnblogs.com/paololiu/p/5070749.html


想要模仿zabbix的oracle插件orabix来实现对db2的监控,但是Java能力有限,就用python来实现了。但是python常用的连接池PooledDB似乎并不支持db2,一直报这样的错误:"Database module is not thread-safe."所幸我只是用来做监控的,要求并不是很高,只要实现连接池的两个基本功能即可:
1.连接复用
2.连接检查,重连


#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import threading,ibm_db,time,Queue

class db2pool(object):
    def __init__(self,host,port,user,password,db,conn_num):
        self.host=host
        self.port=port
        self.user=user
        self.password=password
        self.db=db
        self.conn_num=conn_num
        
        self.conn_queue=Queue.Queue(0)
                        
        for i in range (0,self.conn_num):
            try:
                conn=(ibm_db.connect("DATABASE="+self.db+";HOSTNAME="+self.host+";PORT="+self.port+";PROTOCOL=TCPIP;UID="+self.user+";PWD="+self.password+";", "", ""))
                self.conn_queue.put(conn)
            except Exception as e:    
                print e
    
    def getconnect(self):
            
        for i in range (0,5):

            if self.conn_queue.qsize()>0:
                conn=self.conn_queue.get()
                
                try:
                    stmt=ibm_db.prepare(conn,"select 1 from sysibm.sysdummy1")
                    ibm_db.execute(stmt)
                    return conn
                except Exception as e:
                    print e
                    try:
                        conn=(ibm_db.connect("DATABASE="+self.db+";HOSTNAME="+self.host+";PORT="+self.port+";PROTOCOL=TCPIP;UID="+self.user+";PWD="+self.password+";", "", ""))
                        self.conn_queue.put(conn)
                    except Exception as e:
                        print e
                
            time.sleep(0.5)
                
        self.logger.echo("warning","get connection error")
            
    def getclose(self,conn):        
        self.conn_queue.put(conn)

#example
def work(pool,i):
    # while True:
    conn=pool.getconnect()
    if conn:
        try:
            pass
            stmt=ibm_db.prepare(conn,"select "+str(i)+" from sysibm.sysdummy1")
            ibm_db.execute(stmt)
            result=ibm_db.fetch_both(stmt)
            while (result):
                print "\nresult[0]="+str(result[0])+"++++"+str(conn)
                result=ibm_db.fetch_both(stmt)
        except Exception as e:
            print e
        finally:
            pass
            pool.getclose(conn)
    time.sleep(5)

if __name__=="__main__":
    pool=db2pool("172.16.2.9","60000","db2inst1","db2inst1","secs",5)
    for i in range (0,50):
        t=threading.Thread(target=work,args=(pool,i,))
        t.start()

因为我自己对python也不熟,这里有个地方我采用了妥协的办法:
我是在调用连接的时候去检查连接是否还存活着,而一般的情况下都是用一个后台的线程每隔一段时间去检查线程的。

我也尝试着这样去做了,但发现一个问题:获取连接队列conn=self.conn_queue.get()这一过程对各方都是平等的,谁抢到就是谁的。如果要做个检查连接的方法,则我希望它获得队列的优先级要高与正常调用的的方法,这样就不会出现连接队列一直被正常调用的方法霸占着,而检查连接的方法却因为抢不到连接而不工作。看来这部分要在实现了可控优先级的队列后才能实现了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值