-
Couldn't load subscription status.
- Fork 38.8k
Description
Affects: Spring Boot 3.3.5
I asked on stackoverflow and also found similar questions there:
https://stackoverflow.com/questions/78022351/spring-boot-jpa-transaction-is-committing-but-record-is-not-getting-inserted
https://stackoverflow.com/questions/78863344/frequent-rollback-on-connection-close-in-spring-boot-with-hikaricp-and-mariadb
The problem:
Simple table:
CREATE TABLE table_master
(
id INTEGER NOT NULL,
name VARCHAR(200),
CONSTRAINT t_master_pk PRIMARY KEY (id)
);Test:
@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Slf4j
class JdbcTest {
private DataSource fbDataSource;
@Autowired
private PlatformTransactionManager transactionManager;
@BeforeEach
public void setUp() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:firebirdsql://localhost:3055//opt/fb/db/DBGDB");
config.setUsername("user");
config.setPassword("passwd");
config.setAutoCommit(false);
fbDataSource = new HikariDataSource(config);
}
private static final String insertQuery = "INSERT INTO table_master(id, name) VALUES(?, ?)";
private static final String cntQuery = "SELECT COUNT(*) FROM table_master";
@Test
public void testFbLoad() throws SQLException {
JdbcTemplate fbJdbcTemplate = new JdbcTemplate(fbDataSource);
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
def.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_COMMITTED);
TransactionStatus status = transactionManager.getTransaction(def);
if (fbJdbcTemplate.update(insertQuery, 1, "Row") == 0) {
throw new RuntimeException("Cannot insert row");
}
transactionManager.commit(status);
Integer cnt = fbJdbcTemplate.queryForObject(cntQuery, Integer.class);
log.info("Rows in table_master: {}", cnt);
}Log:
2024-11-30T04:10:31.534+02:00 DEBUG 15966 --- [ Test worker] o.h.e.t.internal.TransactionImpl : On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
2024-11-30T04:10:31.535+02:00 DEBUG 15966 --- [ Test worker] o.h.e.t.internal.TransactionImpl : begin
2024-11-30T04:10:31.536+02:00 DEBUG 15966 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@ea34dee]
2024-11-30T04:10:31.536+02:00 DEBUG 15966 --- [ Test worker] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2024-11-30T04:10:31.537+02:00 DEBUG 15966 --- [ Test worker] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO table_master(id, name) VALUES(?, ?)]
2024-11-30T04:10:31.537+02:00 DEBUG 15966 --- [ Test worker] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2024-11-30T04:10:31.544+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.553+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.553+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.567+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.568+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.570+02:00 DEBUG 15966 --- [ Test worker] o.f.jaybird.xca.FBManagedConnection : End called: Xid[413118226]
2024-11-30T04:10:31.573+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.573+02:00 DEBUG 15966 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:10:31.574+02:00 DEBUG 15966 --- [ Test worker] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-1 - Executed rollback on connection org.firebirdsql.jdbc.FBConnection@394e21b9 due to dirty commit state on close().
2024-11-30T04:10:31.574+02:00 DEBUG 15966 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2024-11-30T04:10:31.574+02:00 DEBUG 15966 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(865867007<open>)]
2024-11-30T04:10:31.574+02:00 DEBUG 15966 --- [ Test worker] o.h.e.t.internal.TransactionImpl : committing
2024-11-30T04:10:31.575+02:00 DEBUG 15966 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(865867007<open>)] after transaction
Problem:
No data inserted due to:
2024-11-30T04:10:31.574+02:00 DEBUG 15966 --- [ Test worker] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-1 - Executed rollback on connection org.firebirdsql.jdbc.FBConnection@394e21b9 due to dirty commit state on close().
Reason:
JdbcTemplate closes connection in the update method. Hikari rolls the transaction back due to the connection' dirty state then. Then JpaTransactionManager tries to commit it but it was already rolled back. So, the example from the Spring docs is not working.
Stack:
doCloseConnection:406, DataSourceUtils (org.springframework.jdbc.datasource)
doReleaseConnection:393, DataSourceUtils (org.springframework.jdbc.datasource)
releaseConnection:360, DataSourceUtils (org.springframework.jdbc.datasource)
beforeCompletion:525, DataSourceUtils$ConnectionSynchronization (org.springframework.jdbc.datasource)
triggerBeforeCompletion:108, TransactionSynchronizationUtils (org.springframework.transaction.support)
triggerBeforeCompletion:996, AbstractPlatformTransactionManager (org.springframework.transaction.support)
processCommit:776, AbstractPlatformTransactionManager (org.springframework.transaction.support)
commit:758, AbstractPlatformTransactionManager (org.springframework.transaction.support)
testFbLoad:105, JdbcTest (com.freewayfleet.dbreplicator)