Context
Я строю постоянный слой для абстрагирования различных типов баз данных, которые мне понадобятся. В реляционной части у меня есть MySQL, Oracle и PostgreSQL.
Давайте возьмем следующие упрощенные таблицы MySQL:
CREATE TABLE Contact (
ID varchar(15),
NAME varchar(30)
);
CREATE TABLE Address (
ID varchar(15),
CONTACT_ID varchar(15),
NAME varchar(50)
);
Я использую код для генерации специфичного для системы буквенно-цифрового уникального идентификатора, подходящего 15 символов в этом случае. Таким образом, если я вставляю запись контакта с ее адресами, у меня появляются сгенерированные Contact.ID и Address.CONTACT_ID перед фиксацией.
Я создал Единицу работы (среди прочих) согласно шаблонам Мартина Фаулера для добавления поддержки транзакций. Я использую Identity Map на основе ключей в UoW для отслеживания измененных записей в памяти. Это работает как очарование для сценария выше, все довольно стандартные вещи до сих пор.
Сценарий вопроса возникает, когда у меня есть база данных, которая не находится под моим контролем, и поля идентификатора имеют автоинкремент (или в последовательностях Oracle). В этом случае у меня нет сгенерированного db Contact.ID заранее, поэтому при создании моего адреса у меня нет значения для Address.CONTACT_ID. Транзакция не была запущена в сеансе БД, поскольку все они хранятся в карте идентификации в памяти.
Вопрос: Какой хороший подход для решения этой проблемы? (Избегая ненужных поездок по БД)
Некоторые идеи:
Получить последний идентификатор: я могу позвонить в базу данных, чтобы получить последний идентификатор, например:
SELECT Auto_increment FROM information_schema.tables WHERE table_name='Contact';
Но это специфично для MySQL, и, вероятно, что-то подобное можно сделать для других баз данных. Если это сделать, необходимо выполнить первую вставку, получить идентификатор и затем обновить дочерние элементы (Address.CONTACT_IDs) - все в контексте текущей транзакции.