Инструменты:
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()
Что происходит:
- при запросе SELECT=r“SELECT p.gissz_num,p.lanaddress FROM … получается краш самого питона и ошибка оракла ora-24550 , которая сводится к обращению в супорт
- если изменить запрос на SELECT=r”SELECT FIRST 10 p.gissz_num,p.lanaddress FROM …, то все отрабатывает как задумывалось. Рабочий диапазон до 12-13 единиц, от чего зависит - непонятно
Результат наводит на мысль, что есть ограничения на потоки именно со стороны DLL Oracle
Или я что-то неграмотно использую ?
И на том спасибо. Решено. На sql.ru откликнулись быстрее
http://www.sql.ru/forum/1068779/obrashhenie-k-bolshomu-kolichestvu-serverov-oracle-s-ispolzovaniem-