Set and reset shared isolation value within synchronized transaction begin

Since EclipseLink applies a custom transaction isolation value to its shared DatabasePlatform instance, we need to immediately restore the original value after the current value got picked up for JDBC Connection access inside of EclipseLink. In order to not interfere with concurrent transactions, we need to use synchronization around the transaction begin sequence in such a case.

Closes gh-29997
This commit is contained in:
Juergen Hoeller
2023-06-04 18:12:40 +02:00
parent 9decbf2158
commit e4bd1344e2
2 changed files with 45 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,8 +27,10 @@ import javax.persistence.Query;
import org.junit.jupiter.api.Test;
import org.springframework.core.testfixture.io.SerializationTestUtils;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.orm.jpa.domain.DriversLicense;
import org.springframework.orm.jpa.domain.Person;
import org.springframework.transaction.TransactionDefinition;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatException;
@@ -114,24 +116,34 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
}
@Test
public void testLazyLoading() {
public void testLazyLoading() throws Exception {
try {
Person tony = new Person();
tony.setFirstName("Tony");
tony.setLastName("Blair");
tony.setDriversLicense(new DriversLicense("8439DK"));
sharedEntityManager.persist(tony);
assertThat(DataSourceUtils.getConnection(jdbcTemplate.getDataSource()).getTransactionIsolation())
.isEqualTo(TransactionDefinition.ISOLATION_READ_COMMITTED);
setComplete();
endTransaction();
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
startNewTransaction();
assertThat(DataSourceUtils.getConnection(jdbcTemplate.getDataSource()).getTransactionIsolation())
.isEqualTo(TransactionDefinition.ISOLATION_SERIALIZABLE);
sharedEntityManager.clear();
Person newTony = entityManagerFactory.createEntityManager().getReference(Person.class, tony.getId());
assertThat(tony).isNotSameAs(newTony);
endTransaction();
assertThat(newTony.getDriversLicense()).isNotNull();
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_DEFAULT);
startNewTransaction();
assertThat(DataSourceUtils.getConnection(jdbcTemplate.getDataSource()).getTransactionIsolation())
.isEqualTo(TransactionDefinition.ISOLATION_READ_COMMITTED);
endTransaction();
assertThat(newTony.getDriversLicense()).isNotNull();
newTony.getDriversLicense().getSerialNumber();
}
finally {