Соединение на запрос, проблема с параллельным выполнением запроса - PullRequest
0 голосов
/ 29 октября 2018

Ниже приведено описание структуры класса доступа к базе данных на основе SQLAlchemy. Есть API-интерфейсы для колб, которые их используют.

Я получаю довольно много исключений нескольких видов с этой структурой. В частности:

Веб-сервис 'X' использует функцию fooBar. Если эта служба получает более одного вызова одновременно , я получаю следующие исключения:

Файл "C: \ Python27 \ lib \ site-packages \ sqlalchemy \ engine \ base.py", строка 1631, в коммите поднять exc.InvalidRequestError («Эта транзакция неактивна») InvalidRequestError: эта транзакция неактивна

Я также случайно получаю следующее:

ProgrammingError: (pyodbc.ProgrammingError) ('24000', '[24000] [Microsoft] [Собственный клиент SQL Server 11.0] Недопустимое состояние курсора (0) (SQLFetch)')

Не говоря уже о нескольких тупиках и откатах, происходящих повсюду.

У меня ощущение, что, возможно, что-то не так в том, как я создаю связь. Похоже, одно и то же соединение используется для всех запросов.

Был бы признателен, если бы кто-то мог указать, что не так с этой структурой кода, и любые другие общие комментарии по этому поводу также приветствуются.

class DBHandler:

 def init(self):        
    try:        
        self.engine = create_engine(SQLALCHEMY_DATABASE_URI, connect_args={'connect_timeout': 10000}, echo=True)

        self.connection = self.engine.connect() 
    except:
        print 'Not connecting to AWS Database'

 def foo(self, skuID):
    try:
        transaction = self.connection.begin()           

        query = "Update Master_SKU SET SKU_Stage = '3' WHERE SKU_ID = ?"            
        results = self.connection.execute(query,skuID)
        transaction.commit()

        return True
    except:
        transaction.rollback()
        return None

 def fooBar(self):
    try:
        transaction = self.connection.begin()           

        query = "SELECT * FROM Master_SKU"          
        results = self.connection.execute(query)
        transaction.commit()

        return True
    except:
        transaction.rollback()
        return None

Редактировать:

Альтернативный подход:

Имеет ли это смысл?

def fooBar(self):
    try:
        tempConnection = self.engine.connect()
        transaction = tempConnection.begin()

        query = "SELECT * FROM Master_SKU"

        rows = tempConnection.execute(query).fetchall()                      
        transaction.commit()
        return True
    except:
        transaction.rollback()
        return False

1 Ответ

0 голосов
/ 29 октября 2018

Вы открываете соединение слишком рано (self.connection = self.engine.connect()). В этот момент вы открыли соединение и ничего не делаете с ним. Вероятно, под капотом происходит то, что база данных открывает для вас соединение и создает блокировку. Пока вы не закроете его, вы не сможете выполнять другие транзакции (например, UPDATE). Это часто случается, например, в PostgreSQL. Попробуйте эту идиому:

connection = self.engine.connect()
# ... perform work
connection.close()

Также см. Связанную проблему: python sqlalchemy + postgresql программа зависает .

...