Управление транзакциями с помощью необработанного SQL и моделей в одной транзакции Django 1.11.49
У меня есть API, который читает из двух основных таблиц Table A и Table B.
В таблице A есть столбец, который имеет столбец, действующий как внешний ключ к записям таблицы B.
Теперь внутри потока api у меня есть метод, который запускает нижеприведенную логику.
- Raw SQL -> Объединение таблицы A с некоторыми другими таблицами и выборка записей, которые имеют активный статус в таблице A.
- Из результата предыдущего запроса мы берем значения из столбца таблицы A и извлекаем связанные строки из таблицы B, используя Django Models.
Это как
query = "Select * from A where status = 1" #Very simplified query just for example
cursor = db.connection.cursor()
cursor.execute(query)
results = cursor.fetchAll()
list_of_values = get_values_for_table_B(results)
b_records = list(B.objects.filter(values__in=list_of_values))
Теперь есть фоновый процесс, который будет вводить или обновлять новые данные в таблице A и таблице B. Этот процесс делает все, используя модели и используя
with transaction.atomic():
do_update_entries()
Однако обновление - это не просто обновление старого ряда. Это похоже на удаление старой строки и удаление связанных строк в таблице B, а затем в обе таблицы добавляются новые строки.
Теперь проблема в том, что если я запускаю api и фоновое задание отдельно, то все хорошо, но когда оба запускаются одновременно, то для многих вызовов api второй запрос таблицы B не получает никаких данных, потому что транзакция выполняется следующим образом:
Table A RAW Transaction executes and read old data
Background Job runs in a single txn and delete old data and enter new data. Having different foreign key values that relates it to Table B.
Table B Models read query executes which refers to values already deleted by previous txn, hence no records
Итак, для чтения всего в одном txn я попробовал следующие варианты
with transaction.atomic():
# Raw SQL for Table A
# Models query for Table B
Это не помогло, и я все еще получаю ту же проблему.
Я попробовал другой способ обхода
transaction.set_autocommit(False)
Raw SQl for Table A
Models query for Table B
transaction.commit()
transaction.set_autocommit(True)
Но и это не сработало. Как я могу прочитать оба запроса в одной транзакции, чтобы обновления фонового задания не повлияли на этот процесс чтения.