Форум сайта python.su
Добрый ! С наступающим !
Инструменты:
1. клиентская часть
w7 x64
Python 3-3-2 x86
fdb 1-4
cx_Oracle-5.1.2-11g.win32-py3.3.msi
драйвер Oracle ODAC v11-2021 Xcopy_32bit
2 серверные - разнообразные Oracle 10g XE, 10g Std, 11g XE, 11g Std разных битностей, но все под Вин
Общая задача: в базе Firebird лежат параметры соединений с серверами Oralce (юзер, ip и тд.). Так исторически сложилось, это обсуждать не нужно. Нужно одновременно сделать запрос на 153 сервера Oracle и снять с них некие данные - сами данные тут не интересны, вопрос в реализации многопоточности при работе с Oracle
Код
# coding: cp1251 import cx_Oracle import fdb import pprint import threading import datetime import pythoncom import time res_spaces_queue=[] ora_mutex=threading.Lock() def get_soft_data(gissz_num,target_host): pythoncom.CoInitialize() ora_con = cx_Oracle.connect("orausr/orapass@"+target_host+"/XE") ora_cur = ora_con.cursor() ora_cur.execute("select dbms_utility.port_string, (select platform_name from v$database) ,(select version from v$instance) from dual") ora_mutex.acquire() for result in ora_cur: res_spaces_queue.append([gissz_num,result[0],result[1],result[2]]) ora_mutex.release() ora_cur.close() ora_con.close() pythoncom.CoUninitialize() #========================================== #========================================== # Main function def main(argv=None): start_time=datetime.datetime.now() fb_conn = fdb.connect(dsn='firebird:d:\\NET_ANALISYS.FDB',user='user',password='password') fb_cur = fb_conn.cursor() SELECT=r"SELECT p.gissz_num,p.lanaddress FROM points p JOIN srv_roles s ON p.id=s.point JOIN srv_roles_types st ON st.id=s.""ROLE"" WHERE p.enabled=1 AND st.name ='ГИССЗ'" fb_cur.execute(SELECT) for row in fb_cur.fetchall(): t = threading.Thread(target=get_soft_data,name='id'+str(row[0]),args=(row[0],row[1],)) t.start() while threading.activeCount()>1: time.sleep(0.25) pprint.pprint(res_spaces_queue) #========================================== if __name__ == "__main__": main()
Отредактировано Ace (Дек. 31, 2013 14:17:47)
Офлайн
Это одна из самых дурацких ошибок, т.к. может быть вызвана разными причинами: от бага в Оракле (на который есть заплатки), специфики работы сессий в Оракле, текущей нагрузки и до плохого кода или конфигурации библиотеки доступа.
Однозначного решения я не встречал. Очевидно, как раз вследствие множественных возможных причин.
Разбираться можно долго (проверять версию каждого сервера, проверять настройки и пр.), поэтому я рекомендую сделать пул потоков и не превышать вручную подобранный размер этого пула.
Либо сделать только одно соединение и использовать его для всех запросов.
Офлайн