Фон
Отказ от ответственности: Я своего рода спящий нуб. Я достаточно разбираюсь в этом, чтобы поддерживать программное обеспечение и вносить некоторые изменения, но не во все тонкости hibernate.
В инфраструктуре play есть интересная особенность, которую каждый https-запрос преобразует в одну транзакцию гибернации. Обычно это круто. Иногда приходит много запросов, которые пытаются вставить один и тот же набор данных, а также выполнять другие действия. Этого действительно нельзя избежать. Это, конечно, приводит к исключению. Естественно, я пытаюсь предотвратить это, спрашивая hibernate, присутствует ли этот набор данных до его вставки, но из-за характера параллелизма эта проверка не мешает другому потоку попытаться вставить данные спустя 3 миллисекунды.
Это также не представляет большой проблемы, если бы не одна транзакция для каждого запроса, на котором работает Play.
Когда hibernate неизбежно выдает ошибку из-за вышеизложенного, вся транзакция должна быть отброшена. Это включает в себя вещи, которые я хочу сохранить. Если бы не это, я просто создал бы отдельную транзакцию и использовал бы эту для вставки данных. Но я не могу, потому что вся моя кодовая база работает в предположении об одной транзакции. Тем не менее, теоретически я мог бы просто закрыть текущую транзакцию и создать новую, но тогда все присоединенные модели были бы отсоединены, и мне нужно было бы найти способ, чтобы сначала выяснить, какие модели были присоединены к старой транзакции, а затем повторно присоединить их. Это имеет свои проблемы. Код проблемного c находится в классе обслуживания, предназначенном для вставки данных такого типа в базу данных. Он понятия не имеет ни о чем другом. Это включает в себя, откуда это называется или в каком контексте. Он не может знать, какие модели подключены в транзакции ... (кроме как, если есть какой-то способ, которым hibernate мог бы сказать мне?) В конце концов, мне все равно, какой поток вставляет данные. Меня интересует только то, что он вообще вставлен. К сожалению, я не могу найти способ обойти эту проблему.
Текущее (безобразное) решение
То, что я сейчас делаю в качестве меры для устранения пробела, заключается в предотвращении параллелизма с использованием очереди. Это, конечно, сильно влияет на производительность, но лучше, чем ничего.
Вопрос
Так что, может быть, есть хитрый способ, который я не знаю, чтобы сказать hibernate, чтобы не бросать при обнаружении дубликата в этой очень конкретной c позиции в моем код?
Пожалуйста, не стесняйтесь обращаться за разъяснениями. Я также был бы очень рад любым предложениям. Я пытаюсь решить эту проблему в течение нескольких дней.