У меня проблема с параллелизмом в Hibernate (версия 5.4.2): важно, чтобы одна сущность (группа классов) всегда имела точный список других сущностей (класс Member). Я использовал двунаправленные отношения с @ OneToMany и @ ManyToOne и @ JoinColumn :
@Entity
public class Group {
@Id
@GeneratedValue
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "group")
private Set<Member> memberList = new HashSet<>();
}
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "groupMember_id")
private Group group;
}
В качестве БД я использую MySQL:
CREATE TABLE `Group` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Member` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`groupMember_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
ALTER TABLE `Member` ADD KEY `FK_2vbvsrpwxwnqbd0rud8kfr9ur` (`groupMember_id`);
ALTER TABLE `Member` ADD CONSTRAINT `FK_2vbvsrpwxwnqbd0rud8kfr9ur` FOREIGN KEY (`groupMember_id`) REFERENCES `Group` (`id`);
Проблема в том, что , если я добавляю вновь созданного Участника в memberList Группы в рамках одной транзакции, другие параллельные транзакции не могут это увидеть - они получают неверный memberList.
Что я пробовал до сих пор:
Как объяснено в https://www.baeldung.com/jpa-pessimistic-locking с LockModeType.PESSIMISTIC_WRITE (с или без PessimisticLockScope.EXTENDED ) с помощью 'find' и 'query'.
Затем я попытался добавить <property name="hibernate.connection.isolation" value="8"/>
к своему persistence.xml . В соответствии с https://www.wideskills.com/hibernate/transactions-and-concurrency-in-hibernate это устанавливает уровень изоляции на Serializable:
Serializable- Это самый строгий уровень изоляции, и он будет иметь проблемы с масштабируемостью. Это предотвращает грязное чтение, фантомное чтение, неповторяемое чтение и т. Д. Транзакции выполняются последовательно (одна за другой) и получает блокировки чтения и записи для всего набора затронутых данных.