MySQL транзакция и буферизованный список запросов

У меня есть код C ++, который анализирует файлы и обновляет базу данных MySQL в соответствии с содержимым этих файлов.
Я запускаю свой код в Windows 10 с MySQL 5.7, и моя база использует движок InnoDB. Вызовы MySQL выполняются через мою собственную оболочку вокруг libmysql.

В попытке оптимизировать этот код, я добавляю запросы на обновление в буфер до достижения максимального размера буфера, затем отправляю весь буфер (содержащий N обновлений) одновременно. Весь этот процесс выполняется внутри одной транзакции.

Вот как выглядит мой код:

MySQLWrapper.StartTransaction();

string QueryBuffer = "";

// Element count is the number of elements parsed from the files
for( int i = 0 ; i < ElementCount ; ++i )
{
bool FlushBuffer =
( i> 0 && ! (( i + 1 ) % N) )    ||
( i == ElementCount - 1 ); // determines if we have reached the buffer max number of requests

QueryBuffer += "INSERT INTO mytable (myfield) VALUES (" Element[ i ] ");";

if( FlushBuffer )
{
MySQLWrapper.SendRequest( QueryBuffer );
QueryBuffer.assign("");
}
}
MySQLWrapper.Commit();

Реализация SendRequest (строка запроса) будет в основном:

void SendRequest(string Request)
{
mysql_query( SQLSocket, Request.c_str())
}

Однако при фиксации транзакции транзакция была прервана: MySQL указывает на то, что состояние неверно для совершения транзакции. Я пытался сделать то же самое, но отправлять запросы только по одному, и эта ошибка не происходит в момент фиксации.

Итак, мои 2 вопроса:

  1. Знаете ли вы, почему факт отправки нескольких запросов одновременно нарушает мою транзакцию?
  2. Вы думаете, что использование буферизованного списка запросов может действительно оптимизировать мой код?

0

Решение

Вместо нескольких INSERT создайте один INSERT с несколькими значениями. IOW, до цикла,
иметь INSERT INTO TABLE (columns), затем внутри цикла, добавить (values), для каждого набора значений.

MySQLWrapper.StartTransaction();

string QueryBuffer = "INSERT INTO mytable (myfield) VALUES ";

// Element count is the number of elements parsed from the files
for( int i = 0 ; i < ElementCount ; ++i )
{
bool FlushBuffer =
( i> 0 && ! (( i + 1 ) % N) )    ||
( i == ElementCount - 1 ); // determines if we have reached the buffer max number of requests

QueryBuffer += "(" Element[ i ] ")";
if( flushbuffer ) {
QueryBuffer += ";";
} else {
QueryBuffer += ",";
}

if( FlushBuffer )
{
MySQLWrapper.SendRequest( QueryBuffer );
QueryBuffer.assign("");
}
}
MySQLWrapper.Commit();

Результирующий оператор SQL будет выглядеть примерно так:

INSERT INTO mytable
(myfield)
VALUES
(1),
(2),
(3),
(3);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]