Я очень расстроен Hibernate!
У меня есть таблица базы данных (mysql), которая содержит отношения родитель-потомок, которые позволяют мне строить дерево категорий. У меня есть несколько потоков, которые можно попытаться получить, и если нет, создать путь к категории (с учетом нескольких строк родитель-потомок) примерно в одно и то же время.
Проблема в том, что я использую только TRANSACTION_READ_COMMITTED, и поэтому могут возникнуть условия гонки, когда поток может создать дочернего родительского элемента для подпути категории, потому что он не нашел его, а затем (вот!) Другой поток сделал это в то же время. Чтобы попытаться решить эту проблему, я наложил уникальное ограничение на родительские / дочерние идентификаторы и уникальное ограничение на полный путь категории. Затем я надеялся, что в моем сеансе я поймаю спящий ConstraintViolationException, и, зная, что другой поток написал для меня новое отношение, я запрашиваю строку, которую другой поток написал в предложении catch. И попробуйте продолжить в этом потоке, выполняя все то, что нужно делать с сеансом.
Это ЕДИНСТВЕННЫЙ способ, с помощью которого я могу решить проблему нескольких потоков, выполняющих работу по получению / созданию одного и того же длинного пути категории (с несколькими строками отношений между родителями и дочерними элементами) в одно и то же время и обеспечения того, чтобы уникальное ограничение сохраняется.
Но hibernate делает недействительным сеанс в ConstraintViolationException и, в конечном счете, выдает исключение утверждения («пустой идентификатор в com.stagirite.bean.Category запись (не сбрасывать сеанс после возникновения исключения)»), поэтому мое решение нежизнеспособно.
Как я собираюсь решить эту проблему во всем приложении для моделей "получить / создать", которые не создают повторяющиеся строки, без использования пессимистической блокировки?
Andy