Я постоянно получаю много исключений тупиковой ситуации.
Я пытаюсь быть максимально подробным и вынимаю весь код, который не имеет отношения.
База данных: SQL Сервер
Зависимости
javax.persistence: javax.persistence-api: 2.2
org.eclipse.persistence: eclipselink: 2.7.0
Классы сущностей
У меня просто есть два класса сущностей, Ticket и Tasks, и один Ticket может иметь много задач.
@Entity
class Ticket {
//Ticket doesnt have any mention to task
...
String status;
//getters and setters
}
@Entity
class Task {
//There is no cascade for updates
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "request_id")
@MapsId("requestId")
private Ticket ticket;
}
Класс обслуживания
public void insertTicketAndTasks(Ticket ticket, ...) throws Exception {
//entityManagerFactory is a singleton initialized at startup
EntityManager entitymanager = entityManagerFactory.createEntityManager();
entitymanager.getTransaction().begin();
entitymanager.persist(ticket);
for (some loop) {
Task task = new Task(....);
entitymanager.persist(task);
}
entitymanager.getTransaction().commit();
entitymanager.close();
}
private List<Ticket> updateTickets(List<Ticket> tickets) {
////entityManagerFactory is a singleton initialized at startup
EntityManager entitymanager = entityManagerFactory.createEntityManager();
List<Ticket> ret = new ArrayList<>();
for (Ticket ticket : tickets) {
ticket.updateLastUpdatedByAndDate(LocalDateTime.now());
ret.add(entityManager.merge(ticket));
}
entitymanager.close();
return ret;
}
Бизнес-класс
Ticket ticket = new Ticket(....)
insertTicketAndTasks(ticket, ....)
//do some operation and set status based on that operation
ticket.setStatus(...);
updateTickets(Collections.singletonList(ticket));
Вот трассировка исключения
01:30:40.095 [main] DEBUG eclipselink.logging.sql - UPDATE ticket SET last_updated_date = ?, status = ?, VERSION = ? WHERE ((request_id = ?) AND (VERSION = ?))
bind => [2020-03-25T01:30:40.094, READY_TO_PUBLISH, 2, 001aff45-1f40-413a-be67-2167a4055854, 1]
01:30:51.197 [main] DEBUG eclipselink.logging.sql - SELECT 1
01:30:51.201 [main] WARN eclipselink.logging.all -
org.eclipse.persistence.exceptions.DatabaseException:
Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Error Code: 1205
Call: UPDATE ticket SET last_updated_date = ?, status = ?, VERSION = ? WHERE ((request_id = ?) AND (VERSION = ?))
bind => [2020-03-25T01:30:40.094, READY_TO_PUBLISH, 2, 001aff45-1f40-413a-be67-2167a4055854, 1]
Query: UpdateObjectQuery(db.entity.Ticket@351ede23)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:905)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:967)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:637)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:564)
I Я уверен, что над этим объектом заявки не работает никакой другой процесс.
На основании некоторых других связанных сообщений я обновляю SQL Настройки изоляции сервера до
SET ALLOW_SNAPSHOT_ISOLATION ON
SET READ_COMMITTED_SNAPSHOT ON
Но это не сильно помочь.