Не знаю, важно ли это, на всякий случай — у меня есть приложение, использующее Spring/ SpringBoot со Spring JPA и другими вещами. База данных — Postgresql, и там все работает нормально.
Проблема в том, что в том же приложении мне нужно подключиться к другой базе данных — Firebird. Я пытаюсь вставить значения в некоторую таблицу в этой базе данных Firebird с помощью Spring JDBC, и похоже, что изменения не зафиксированы.
Я создал простую таблицу для тестов:
Код: Выделить всё
CREATE TABLE table_master
(
id INTEGER NOT NULL,
name VARCHAR(200),
CONSTRAINT t_master_pk PRIMARY KEY (id)
);
Код: Выделить всё
@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/DB.GDB");
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);
for (int i = 0; i < 100; i++) {
if (fbJdbcTemplate.update(insertQuery, i, "Row #" + i) == 0) {
throw new RuntimeException("Cannot insert row #" + i);
}
}
transactionManager.commit(status);
Integer cnt = fbJdbcTemplate.queryForObject(cntQuery, Integer.class);
log.info("Rows in table_master: {}", cnt);
}
Код: Выделить всё
@Test
public void testFbLoad() throws SQLException {
JdbcTemplate fbJdbcTemplate = new JdbcTemplate(fbDataSource);
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(status ->
{
try {
for (int i = 0; i < 100; i++) {
if (fbJdbcTemplate.update(insertQuery, i, "Row #" + i) == 0) {
throw new RuntimeException("Cannot insert row #" + i);
}
}
} catch (Exception e) {
log.error("Rolling back: {}", e.getMessage(), e);
status.setRollbackOnly();
}
return null;
}
);
Integer cnt = fbJdbcTemplate.queryForObject(cntQuery, Integer.class);
log.info("Rows in table_master: {}", cnt);
}
Понятия не имею, что я делаю не так. Помогите, пожалуйста, как мне использовать Spring JDBC для таких задач?
Обновление:
Ну, я попробовал @Transactional, и это также дает мне странный результат:
Код: Выделить всё
@Test
@Transactional
public void testFbLoad() throws SQLException {
JdbcTemplate fbJdbcTemplate = new JdbcTemplate(fbDataSource);
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(status ->
{
try {
for (int i = 0; i < 100; i++) {
if (fbJdbcTemplate.update(insertQuery, i, "Row #" + i) == 0) {
throw new RuntimeException("Cannot insert row #" + i);
}
}
status.setRollbackOnly();
} catch (Exception e) {
log.error("Rolling back: {}", e.getMessage(), e);
status.setRollbackOnly();
}
return null;
}
);
Integer cnt = fbJdbcTemplate.queryForObject(cntQuery, Integer.class);
log.info("Rows in table_master: {}", cnt);
}
Пожалуйста, помогите. Спасибо!
Обновление 2:
похоже, я нашел причину. Вот журнал:
Код: Выделить всё
2024-11-30T04:00:50.693+02:00 DEBUG 15770 --- [ Test worker] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update
2024-11-30T04:00:50.693+02:00 DEBUG 15770 --- [ Test worker] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO table_master(id, name) VALUES(?, ?)]
2024-11-30T04:00:50.693+02:00 DEBUG 15770 --- [ Test worker] o.s.jdbc.datasource.DataSourceUtils : Fetching JDBC Connection from DataSource
2024-11-30T04:00:50.701+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.711+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.711+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.724+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.726+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.728+02:00 DEBUG 15770 --- [ Test worker] o.f.jaybird.xca.FBManagedConnection : End called: Xid[1219176952]
2024-11-30T04:00:50.731+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.731+02:00 DEBUG 15770 --- [ Test worker] o.f.gds.ng.wire.AbstractWireOperations : readStatusVector arg:isc_arg_gds int: 0
2024-11-30T04:00:50.731+02:00 DEBUG 15770 --- [ Test worker] com.zaxxer.hikari.pool.ProxyConnection : HikariPool-1 - Executed rollback on connection org.firebirdsql.jdbc.FBConnection@5f5fe604 due to dirty commit state on close().
2024-11-30T04:00:50.731+02:00 DEBUG 15770 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
2024-11-30T04:00:50.732+02:00 DEBUG 15770 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [SessionImpl(1821322830)]
2024-11-30T04:00:50.732+02:00 DEBUG 15770 --- [ Test worker] o.h.e.t.internal.TransactionImpl : committing
2024-11-30T04:00:50.733+02:00 DEBUG 15770 --- [ Test worker] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [SessionImpl(1821322830)] after transaction
Спасибо!
Подробнее здесь: https://stackoverflow.com/questions/792 ... -committed
Мобильная версия