У вас есть варианты.
1) Примитивно, но просто, поймайте ошибку нарушения ключа в конце и повторите попытку вставки без родителей.Предполагая, что ваши родители действительно уникальны, вы знаете, что другой поток только что родители ... продолжить с детьми.Это может плохо работать по сравнению с другими вариантами, но, возможно, вы получите нужную вам популярность.Если бы у вас был высокий процент родителей с одним ребенком, это бы сработало.
2) Измените уровень согласованности чтения.Это зависит от поставщика, но иногда вы можете прочитать незафиксированные транзакции.Это поможет вам увидеть работу других потоков перед фиксацией.Это не надежно, вы все равно должны сделать # 1, так как другой поток может проникнуть после чтения.Но это может улучшить вашу пропускную способность за счет большей сложности.Это может быть невозможным, на основе СУБД (или, может быть, это может случиться, но только на уровне БД, путаясь в других приложениях!)
3) Реализация рабочей очереди с однопоточным потребителем.Если основная дорогостоящая работа программы выполняется до уровня персистентности, ваши потоки могут «вставить» свои данные в рабочую очередь, где ключи не применяются.Затем вытащите один поток из рабочей очереди и сохраните его.Рабочая очередь может находиться в памяти, в другой таблице или в определенном поставщике месте (Weblogic Queue, Oracle AQ и т. Д.).Если основная работа программы перед сохранением, вы распараллеливаете ЭТО и возвращаетесь к одному потоку на вставках.Вы даже можете заставить своего потребителя работать в режиме «пакетной вставки».Sweeeeeeeet.
4) Расслабься.Кого волнует, если у одного и того же ребенка есть два родителя с одинаковой информацией?Я просто спрашиваю.Если вам позже не нужны супербыстрые обновления родительской информации, и вы можете изменить свои программы чтения, чтобы понять это, это может работать хорошо.Он не получит «A» в классе проектирования БД, но если это сработает .....
5) Реализовать глупую таблицу блокировок.Я ненавижу это решение, но оно работает - пусть ваш поток записывает, что он работает с родительским «x», и никто другой не может сделать это в качестве первой транзакции (и фиксации).Обычно приводит к той же самой проблеме (и другим - очистка записей позже, и т. Д.), Но может работать, когда вставки потомков выполняются медленно, а вставка в одну строку - быстро.У вас все еще будут столкновения, но меньше.