Open BbIKTOP opened 4 days ago
Can not be reproduced by H2.
import static org.assertj.core.api.Assertions.assertThat;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@org.springframework.boot.test.autoconfigure.jdbc.JdbcTest
@ContextConfiguration(classes = JdbcTest.class)
@Sql(statements = "CREATE TABLE table_master(id INTEGER NOT NULL,name VARCHAR(200),CONSTRAINT t_master_pk PRIMARY KEY (id))")
class JdbcTest {
@Autowired
private DataSource dataSource;
@Autowired
private PlatformTransactionManager transactionManager;
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 test() throws SQLException {
JdbcTemplate fbJdbcTemplate = new JdbcTemplate(dataSource);
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);
assertThat(cnt).isEqualTo(1);
}
}
Looks like it fails with custom datasource
As mentioned in the stackoverflow issue, the datasource isnt even known to Spring and the PlatformTransactionManager
in use is tied to another DataSource
so won't manage the transactions. As the auto-commit
is set to false you are basically running without a transaction, no transaction no persisting.
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:
Test:
Log:
Problem:
No data inserted due to:
Reason:
JdbcTemplate
closes connection in the update method. Hikari rolls the transaction back due to the connection' dirty state then. ThenJpaTransactionManager
tries to commit it but it was already rolled back. So, the example from the Spring docs is not working.Stack: