pyodb c cursor.execute зависает, когда много соединений сделано с разных устройств - PullRequest
0 голосов
/ 18 января 2020

Почти 10 raspberry pi использует тот же скрипт, что и упомянутый ниже, и пытается отправлять данные в базу данных каждую минуту (почти одновременно).

Почти нет проблем, когда только одно устройство связывается с базой данных, но проблема начинается, когда я начинаю добавлять больше Raspberry Pi.


Code:

import pyodbc 

def update_database():
        try:            
            mydb = pyodbc.connect('DRIVER=FreeTDS;SERVER=192.xxx.xxx.xxx;PORT=xxxx;DATABASE=xxxxxxx;UID=xxxxxxx;PWD=xxxxxxx;TDS_Version=4.2;')
            mycursor = mydb.cursor()

            if mycursor.tables(table='DBDBDBDB', tableType='TABLE').fetchone():
                print("DB exists")
            else:
                print("DB absent")
                DB_Connection_status=0


            ycursor = mydb.cursor()            
            sql = "INSERT INTO DBDBDBDB (docdt, timestamp, cocd, param1, param2, param3, param4, param5, param6, param7, param8) \
                    VALUES (?,?,?,?,?,?,?,?,?,?,?)"


            DB_Connection_status=1
            systemlog("DB Connected")
        except:
            DB_Connection_status=0
            print ("Connection with database: failed")
            systemlog("DB Not Connected")



        for index_y in range (0,6):
            #few lines of code here

            for index_x in range (0,60): 
                #few lines of code here

                if(DB_Connection_status==1):

                    val = (formatted_date, formatted_time, COCD, str(var1), \
                           str(var2), str(var3),\
                           'A','1', str( var4[index_y][index_x]), \
                           str(var5[index_y][toggle_sw_num-1]),0)
                    try:
                        mycursor.execute(sql, val)
                    except:
                        systemlog("DB record skipped")


        if(DB_Connection_status==1):
            try:
                mydb.commit()
                print(mycursor.rowcount, "record inserted.")
                systemlog("Record inserted")
            except:
                systemlog("DB commit skipped")

while 1:
    #few lines of code here
    if(system_minute!=oldsystem_minute):
        oldsystem_minute=system_minute
        #few lines of code here
        update_database()


Изначально выдает ошибку, как показано ниже, прежде чем я добавил обработку ошибок для выполнения курсора и фиксации

Traceback (most recent call last):
  File "mod.py", line 461, in <module>
  File "mod.py", line 213, in update_database
pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS][SQL Server]Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. (1205) (SQLExecDirectW)')

Но эта обработка ошибок просто чтобы избежать кода cra sh.

Есть ли какие-либо проблемы в последовательности кода? Например, я должен вызывать commit / close каждый раз, когда выполняется курсор? Любая помощь по этому поводу?

ОС: Rasbian работает на Raspberry Pi, Python: 2,7, DB: MS SQL

Спасибо

1 Ответ

0 голосов
/ 18 января 2020

я должен вызывать commit / close каждый раз при выполнении курсора?

Да. commit(). Блокировки на вставленные строки и индексы удерживаются на протяжении транзакции. commit() снимет все блокировки для этого сеанса.

Если фиксация после каждой строки является проблемой производительности, вы можете включить отсроченный срок службы или вместо вложенного l oop с однострочными вставками создайте документ JSON со всеми 360 строками, отправьте его на SQL сервер и получите SQL сервер для анализа и INSERT в одном выражении.

...