Страницы

Поиск по вопросам

понедельник, 30 декабря 2019 г.

Транзакционная модель

#cpp #mysql #innodb


В рамках многопоточного приложения работа с БД осуществляется посредством использования
одной и той же учётной записи. Каждый поток имеет отдельное соединение с БД. Появилась
необходимость использовать транзакции.

В официальной документации мне не удалось обнаружить (буду признателен за ссылку),
где бы чётко оговаривалось, что транзакционная модель в InnoDb функционирует и на уровне
соединений, а не только на уровне отдельных учётных записей. Возможно, что это априори,
однако я некомпетентен в рассматриваемой области. Хотелось бы, по возможности, получить
точный ответ.

Второй вопрос вытекает из первого. Если транзакционная модель InnoDb всё же реализована
на уровне отдельных соединений, то существует ли также возможность создавать отдельные,
но параллельно выполняемые транзакции в рамках одного и того же соединения в одном
и том же потоке? Это, скажем, может понадобиться при асинхронном выполнении. К сожалению,
в документации я не увидел возможности указывать транзакциям какие-либо уникальные
имена или идентификаторы.

MySQL 5.7
    


Ответы

Ответ 1



Транзакционная модель функционирует, как ни странно, на уровне транзакций - группы команд между begin и commit/rollback (одиночные запросы вне открытой явно транзакции автоматически оборачиваются в транзакцию, без транзакции транзакционные хранилища не работают). В рамках одного соединения может быть много транзакций. От одного пользователя может быть много одновременных и независимых соединений, и, следовательно, конкурентных транзакций тоже может быть много. В сущности, в понятии транзакции нет ни соединения, ни пользователя. Есть только id транзакции, согласно которому вычисляется видимость актуальных версий строк в MVCC и за которым закрепляются взятые блокировки. В известных мне СУБД - mysql и postgresql - одно соединение одновременно держать две разные транзакции открытыми не может, одно соединение - только одна открытая транзакция. И не припоминаю возможности в рамках одного соединения выполнять одновременно несколько команд. Библиотека может предоставлять неблокирующий вызов, но не дождавшись конца ответа новые запросы отправлять не получится.

Ответ 2



В MySQL каждый тред держит соединение. Он не отслеживает, каким процессом это соединение открыто, т.е. ему без разницы, один процесс открыл кучу соединений или это куча процессов. MySQL выполняет запросы параллельно, в рамках тредной модели, но существуют блокировки: на уровне MySQL в целом: на метаданные транзакционные на уровне движка (InnoDb) на таблицы, в случае индексации, оптимизации счетчик автоинкремента на таблицу в случае записи на строки LOCK TABLE полный скан таблицы (индексация) В случае транзакций: После того как стартует транзакция - происходят какие-то изменения данных, которые пишутся в журнал, далее мы эти изменения коммитим или отменяем. Как только мы выполнили эти изменения, то они из журнала переходят в данные. На время выполнения транзакции - данные используемой табл доступны для чтения (но это зависит от уровня изоляции транзакции). В рамках одного соединения может стартовать только одна транзакция. COMMIT закрепляет транзакцию. Советую книгу MySQL. «Оптимизация производительности», там очень хорошо расписано про блокировки и транзакции.

Комментариев нет:

Отправить комментарий