Мне было любопытно, являются ли методы весеннего jparepository потокобезопасными, а затем я прочитал статью о стеке (Is a Spring Data (JPA) Repository thread-safe? (aka is SimpleJpaRepository thread safe)). Оттуда я понял, что методы репозитория являются потокобезопасными, а затем я сделал один POC для проверки безопасности потока. Я сделал один репозиторий, говоря, что FormRepository выполняет операции CRUD для объекта form, который расширяет JpaRepository. Из DAO я просто вызвал 100 потоков, создающих объект формы, и вручную установил свой идентификатор, а затем сохранил объект «форма».Что касается Spring JpaRepository метод безопасности потока
Ниже приведен код для справки: -
@Repository
public interface FormRepository extends JpaRepository<Tbldynamicform, Long> {
Tbldynamicform save(Tbldynamicform tblform);
@Query("SELECT max(tblform.formid) FROM Tbldynamicform tblform")
Optional<Integer> findMaxId();
}
......End of Repository above and start of DAO below...
@Component
public class DynamicFormDAO implements DynamicFormDAO {
@Inject
private FormRepository formRepository;
public void testThreadSafety() throws Exception {
List<Callable<Integer>> tasks = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
tasks.add(() -> {
try {
Tbldynamicform tbldynamicform = new Tbldynamicform();//Set all the required fields for form
if (tbldynamicform.getFormid() == null)
tbldynamicform.setFormid(findFormID());
Tbldynamicform form = formRepository.save(tbldynamicform);
return form.getFormid();
} catch (Exception e) {
e.printStackTrace();
}
return null;
});
}
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.invokeAll(tasks);
}
private int findFormID() throws Exception {
Optional<Integer> id = formRepository.findMaxId();
if (id != null && id.isPresent() && id.get() != null) {
int generatedId = id.get().intValue();
return ++generatedId;
}
return 0;
}
}
Когда я делаю это, я предполагаю, что вещи должны работать хорошо, потому что методы формы хранилищ являются поточно, но каким-то образом я получаю SQL dataintegrityviolationexception несколько раз в журналах, в результате чего происходит сбой нескольких записей. Ниже приведена ошибка для справки: -
org.springframework.dao.DataIntegrityViolationException: не удалось выполнить инструкцию; SQL [n/a]; ограничение ["ПЕРВИЧНЫЙ КЛЮЧ НА PUBLIC.TBLDYNAMICFORM (FORMID)"; SQL заявление: вставки в Tbldynamicform (ClientID, copyfromexisting, CreationDate, formdesc, formmode, FormName, formtemplate, formtitle, procutype, статус, FormID) значений (,, ...
Это сделал?? мне кажется, что это проблема безопасности потоков или какой-то другой проблемы? По моему мнению, все объекты tbldynamicform, которые я создал в моем dao, будут оставаться в стеке стека. Только formRepository будет находиться в хранилище кучи и если методы formrepository являются потокобезопасными, 100 записей должны быть вставлены в базу данных без каких-либо проблем.
Если я делаю setId и сохраняю в синхронизированном блоке, все работает нормально, но это не мое намерение и не требуется, если методы репозитория являются потокобезопасными.
Эксперты, любая помощь, пожалуйста?
Да, я тоже думал так же, потому что, поскольку я также задал свой вопрос, что если я поместил save и findformId в синхронизированный блок, все будет хорошо. –