Я, наконец, выяснил проблему. Итак, позвольте мне объяснить один за другим. Прежде всего, посмотрите на
Propagation.REQUIRES_NEW does not create a new transaction in Spring with JPA
Тогда, например, у нас есть класс и метод, как:
public class MyClass{
@Transactional
public void myMethod(){
....
}
}
Итак, в первую очередь, позволяет считать, что MyMethod находится в своем собственном транзакция полностью, потому что транзакции основаны на AOP, и они будут выполняться, когда соответствующий аспект будет срабатывать, но только после завершения метода, исключения исключений и т. д. Таким образом, мы не можем частично совершать, частично откатываться, откатывать не полностью и т. д. Таким образом, мы должны сделать следующее:
- Начало большой внешняя транзакция
- Начать новую вложенную транзакцию, попробуйте вставить запись.
- Если вложенная транзакция не удалась, она будет отброшена назад, но внешний будет работать.
- Если первая вложенная транзакция завершилась неудачно, запустите новую вложенную транзакцию и вставьте запись с новыми данными, что предотвратит выброс ConstaintViolationException.
Таким образом, в этом случае, мы создаем класс:
public class ServiceHelper{
@Transational(proparation = **Propagation.REQUIRED_NEW**)
public void tryConstraint throws MyConstraintException{
try{
//insert
}catch(ConstraintViolationException e){
throw new MyConstraintException(e);
}catch(Exception ex){
throw new Exception(ex);
}
}
@Transational(proparation = **Propagation.REQUIRED_NEW**)
public void insertWithNoConflict throws Exception {
//Set new data
//insert, if still CVE or anything other, just throw it , or leave it for unchecked exceptions then
}
}
И наш сервис:
public class MyService{
@Autowired
private ServiceHelper serviceHelper;
@Transactional(propagation = **Propagation.REGUIRED_NEW**)
public void createWithCheck(){
try{
serviceHelper.tryConstraint();
}catch(MyConstraintException e){
serviceHelper.insertWithNoConflict();
}
}
}
Но есть еще странная ситуация, потому что мне нужно использовать методы MYSERVICE для создание записей в ServiceHelper, но я не могу их получить там, потому что это вызовет круговые инъекции, поэтому я должен получить их через сервисные фабрики, например:
MyService service = (MyService)ServicesFactory.getInstance().getBean(MyService.BEAN_ID)
И мне это не нравится. Но этот подход работает, я проверил его сегодня.
Мы должны знать 2 вещи: прежде всего мы ничего не можем сделать с транзакцией внутри метода, мы не можем начинать там никаких новых транзакций и т. Д. Контекст транзакции имеет отношение к методу полностью, он все равно будет быть там до окончания метода. И второе: required_new не работает, когда мы запускаем метод из метода того же самого прокси-класса.
Я не уверен, какой у вас конкретный вопрос. Вы говорите, что предпочли бы, чтобы система присваивала уникальное значение, но вынуждены поймать ConstraintViolation, когда это произойдет. В этот момент вы готовы присвоить новое значение и повторите попытку. Что вы пробовали и какие у вас проблемы? –
Извините, я только что редактировал свое сообщение. Спасибо – avalon