Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Эксперименты с транзакциями / 10 сообщений из 10, страница 1 из 1
07.05.2018, 10:42
    #39641254
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
Кассовая программа под Windows с локальной однопользовательской базой. Все таблицы INNODB. Среда разработки Delphi2007, для связи с базой используются компоненты MyDAC.

Рабочий вариант, до начала экспериментов (транзакции не использовались от слова "совсем", все работало в режиме autocommit):

1. Запись заголовка чека: в TMyQuery подается запрос следующего вида с набором параметров:
Код: sql
1.
2.
3.
insert into checks(.....) values (.....);
SELECT  LAST_INSERT_ID() into @CheckId;
SELECT @CheckId as CheckId;



2. Запись строк чека: полученный CheckId возвращается в приложение, далее через TMyCmd подается следующая команда с параметром :CheckId
Код: sql
1.
insert into check_items(CheckId, ....) values (:CheckId, .....);



3. Процедура расчета скидок, также отдельной командой через TMyCmd с параметром :CheckId
Код: sql
1.
call proc_calc_discount(:CheckId);



4. Процедура расчета доступных лимитов и переноса данных в промежуточные таблицы
Код: sql
1.
call proc_prepare_temp_items(:CheckId);



Тестовый вариант:
Логика не изменилась, но до начала записи в базу формируется единый скрипт следующего вида, который передается в TMyQuery:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
START TRANSACTION;
SET @CheckId = null;
insert into checks(.....) values (.....);
SELECT  LAST_INSERT_ID() into @CheckId;
insert into check_items(CheckId, ....) values (@CheckId, .....);
call proc_calc_discount(@CheckId);
call proc_prepare_temp_items(@CheckId);
COMMIT;
SELECT @CheckId as CheckId;


В обоих случаях фиксирую в логах приложения время начала и окончания выполнения всей последовательности действий.

Казалось бы, с использованием транзакций должно стать как минимум не хуже, но все вышло с точностью до наоборот. Если верить логам, в MySQL 5.6 единый скрипт выполняется в среднем на 30% дольше, чем последовательность из нескольких команд. Для эксперимента использовались два не самых слабых терминала 2Гб/2ГГц.

В чем может быть причина?
...
Рейтинг: 0 / 0
07.05.2018, 11:08
    #39641270
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
A-MaRВ чем может быть причина?Наверное, в том, что на организацию транзакции тоже нужны некие ресурсы?
А нахрена потребовалось всё это заворачивать в транзакцию? тем более явно без понимания сути - ибо настройки параметров транзакции не видать, и Вы про них ничего не говорите...

Ну и - две строки
Код: sql
1.
2.
SELECT  LAST_INSERT_ID() into @CheckId;
SELECT @CheckId as CheckId;

вполне можно заменить одной
Код: sql
1.
SELECT @CheckId := LAST_INSERT_ID() as CheckId;


а поскольку переменная больше нигде не используется, так и просто
Код: sql
1.
SELECT LAST_INSERT_ID() as CheckId;
...
Рейтинг: 0 / 0
07.05.2018, 12:00
    #39641319
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
AkinaА нахрена потребовалось всё это заворачивать в транзакцию?
Такая мысль возникла в ходе тестирования под MySQL 8.0, так как в этой версии без использования транзакций все работает намного медленнее. Для остальных версий сервера я предусмотрел возможность отключения строк START TRANSACTION и COMMIT.
Akinaибо настройки параметров транзакции не видать, и Вы про них ничего не говорите
Если Вы про уровень изоляции, то устраивает REPEATABLE READ, используемый по умолчанию. Или есть еще какие-то настройки?
...
Рейтинг: 0 / 0
07.05.2018, 12:23
    #39641337
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
A-MaRЕсли Вы про уровень изоляции, то устраивает REPEATABLE READ, используемый по умолчанию. Или есть еще какие-то настройки?Нет, именно о них. Вернее, о том, что не надо надеяться на что-то "по умолчанию", лучше всегда ставьте явно - во избежание сюрпризов, тем более что это дешёвая операция.
...
Рейтинг: 0 / 0
08.05.2018, 10:43
    #39641868
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
В общем, зря я грешил на транзакции - их отключение ничего не изменило. Зато тормоза исчезли после того как я:
- избавился от переменной @CheckId, выделив получение этого идентификатора в отдельную операцию и подставляя во все остальные уже готовое значение в явном виде
- везде, где не требуется возвращать значение, заменил TMyQuery на TMyCommand
- указал явно уровень изоляции (Akina - благодарю за подсказку).

Вроде как вопрос решен.
...
Рейтинг: 0 / 0
10.05.2018, 18:44
    #39642876
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
Еще вопрос: если выполняется большой скрипт через командную строку с помощью команды mysql, и где-то между START TRANSACTION и COMMIT происходит ошибка - как правильно в этом случае откатить транзакцию? Если просто из приложения отправить ROLLBACK - не сработает, это же фактически уже другое соединение? Или я не прав?
...
Рейтинг: 0 / 0
10.05.2018, 20:46
    #39642920
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
A-MaRЕще вопрос: если выполняется большой скрипт через командную строку с помощью команды mysql, и где-то между START TRANSACTION и COMMIT происходит ошибка - как правильно в этом случае откатить транзакцию?
Вопрос снимается, в случае MyDAC правильный ответ - юзать компонент TMyScript :)
...
Рейтинг: 0 / 0
11.05.2018, 07:26
    #39642996
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
A-MaRкак правильно в этом случае откатить транзакцию?В скрипте должен быть определён обработчик ошибки (см. CREATE HANDLE). Именно там в случае ошибки и выполняется откат.
...
Рейтинг: 0 / 0
11.05.2018, 07:53
    #39642998
A-MaR
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
AkinaВ скрипте должен быть определён обработчик ошибки (см. CREATE HANDLE). Именно там в случае ошибки и выполняется откат.
Это если используются процедуры. А в моем случае в скрипте просто несколько мульти-insert-ов, сформированных динамически при парсинге текстового файла и обрамленных в транзакцию.
...
Рейтинг: 0 / 0
11.05.2018, 08:43
    #39643008
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эксперименты с транзакциями
Условная обработка возможна либо в процедуре, либо вручную. Анонимных блоков в MySQL нет...

Конвертируйте в процедуру, типа
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
DELIMITER @@;
CREATE PROCEDURE proc
BEGIN
  DECLARE EXIT HANDLER FOR ...
    BEGIN
      ROLLBACK;
    END;
  START TRAN;
  INSERT ... ;
  INSERT ... ;
  ... ;
  COMMIT;
END;
@@;
DELIMITER ;
CALL proc;
DROP PROCEDURE proc;
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Эксперименты с транзакциями / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]