Несколько транзакций базы данных на одном соединении - PullRequest
3 голосов
/ 11 декабря 2008

У меня многопоточная программа, тогда как каждый поток в начале выполнения получает одно соединение из класса пула соединений MySql. Затем поток использует ряд классов-оболочек таблиц базы данных для выполнения своей бизнес-логики, передавая соединение с базой данных классам-оболочкам. Операции над этими классами-обертками не обязательно являются последовательными, и я хочу, чтобы эти классы-обертки могли фиксировать или откатывать изменения в своей таблице базы данных независимо друг от друга с помощью одного подключения к базе данных. Я знаю, что MySql не разрешает вложенные транзакции и не нашел способ сделать это. Любая помощь очень ценится. Спасибо!

Ответы [ 5 ]

2 голосов
/ 11 декабря 2008

Звучит так, как будто вы должны связывать транзакции с обертками таблиц лучше, чем просто по потокам. IOW, вам нужно создать класс транзакции. Класс транзакции получает / освобождает соединения из / в пул соединений при открытии и закрытии транзакции.

Транзакция станет фабрикой для ваших оберток. Любая оболочка таблицы, созданная транзакцией, находится внутри транзакции, поскольку она не имеет доступа ни к какому соединению, кроме той, к которой относится транзакция.

Раздражает то, что все объекты не имеют доступа к мертвым объектам. Некоторая форма SmartPtr потребуется для обработки того, что происходит, когда транзакция фиксируется, но что-то пытается снова использовать оболочку таблицы.

1 голос
/ 11 декабря 2008

Самое простое решение - просто создать новое соединение для каждого потока - так обычно это делается с Apache / PHP.

Если у вас гораздо меньше операций записи, чем операций чтения (для записи требуется только 1 из 10 потоков), вы можете использовать одно глобальное соединение для SELECT и создать новое соединение для каждого потока, который необходимо обновить.

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

1 голос
/ 11 декабря 2008

Есть пул соединений, почему бы вам не приобрести больше соединений? И, возможно, использовать семафоры, чтобы ограничить количество одновременных подключений. Иначе, вам нужно заблокировать одиночное соединение или использовать клиентские транзакции (используйте платформу, это не просто, и вам все равно нужно заблокировать соединение, если оно есть, но время ожидания будет очень маленьким по сравнению с отсутствием транзакций на вашей стороне кода).

1 голос
/ 11 декабря 2008

Ну, это классический пример использования одного ресурса несколькими потоками.

Решение заключается в использовании мьютексов в операциях подключения mysql.

1 голос
/ 11 декабря 2008

Если я правильно понимаю проблему, я считаю, что ваш единственный вариант - реализовать какую-то очередь транзакций, которая позволяет нескольким потокам совместно использовать одно соединение. Каждый из ваших потоков может затем добавить «задачи» в очередь, которые требуют выполнения внутри транзакции. Затем у вас есть процесс, который выбирает эти задачи из очереди (вы могли бы даже реализовать какой-то приоритет здесь) и отправляет их в базу данных, прежде чем возвращать результаты в поток, который инициировал запрос. Вызывающие потоки будут блокироваться, пока они не получат свои результаты, что не идеально, но если вам действительно нужно иметь несколько потоков и несколько транзакций, я не вижу другого способа сделать это, не имея нескольких соединений.

...