我有以下彈簧資料源設定:
datasource:
name: postgres-datasource
url: ${POSTGRES_URL:jdbc:postgresql://localhost:5432/mydb}?reWriteBatchedInserts=true&prepareThreshold=0
username: ${POSTGRES_USER:mydb}
password: ${POSTGRES_PASS:12345}
driver-class: org.postgresql.Driver
hikari:
minimumIdle: 2
maximum-pool-size: 30
max-lifetime: 500000
idleTimeout: 120000
auto-commit: false
data-source-properties:
cachePrepStmts: true
useServerPrepStmts: true
prepStmtCacheSize: 500
jpa:
database-platform: org.hibernate.dialect.PostgreSQLDialect
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
# generate_statistics: true
order_inserts: true
order_updates: true
jdbc:
lob:
non_contextual_creation: true
batch_size: 50
請注意,自動提交是false.
因為,我需要同時使用 jooq 和 JPA,并且在我的資料庫中也有多個模式,所以我配置了以下內容DataSourceConnectionProvider
public class SchemaSettingDataSourceConnectionProvider extends DataSourceConnectionProvider {
public SchemaSettingDataSourceConnectionProvider(TransactionAwareDataSourceProxy dataSource) {
super(dataSource);
}
public Connection acquire() {
try {
String tenant = TenantContext.getTenantId();
log.debug("Setting schema to {}", tenant);
Connection connection = dataSource().getConnection();
Statement statement = connection.createStatement();
statement.executeUpdate("SET SCHEMA '" tenant "'");
statement.close();
return connection;
} catch (SQLException var2) {
throw new DataAccessException("Error getting connection from data source " dataSource(), var2);
}
}
我有@EnableTransactionManagementspring boot 配置。有了這個設定,連接在事務結束后不會提交。
@Transactional(propagation = Propagation.REQUIRES_NEW)
public FlowRecord insert(FlowName name, String createdBy) {
return dslContext.insertInto(FLOW, FLOW.NAME, FLOW.STATUS)
.values(name.name(), FlowStatus.CREATED.name())
.returning(FLOW.ID)
.fetch()
.get(0);
}
這不承諾。所以,我嘗試將以下代碼添加到我的SchemaSettingDataSourceConnectionProvider課程中
@Override
public void release(Connection connection) {
connection.commit();
super.release(connection);
}
然而,現在的問題是,即使事務應該回滾,例如由于運行時例外,它仍然會一直提交。
我缺少一些配置嗎
更新
按照下面的答案,我提供了一個DataSourceTransactionManager bean,它適用于 JOOQ。
public DataSourceTransactionManager jooqTransactionManager(DataSource dataSource) {
// DSTM is a PlatformTransactionManager
return new DataSourceTransactionManager(dataSource);
}
但是,現在我的常規 JPA 呼叫都失敗了
Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.internal.AbstractSharedSessionContract.checkTransactionNeededForUpdateOperation(AbstractSharedSessionContract.java:445)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1692)
所以,我提供了一個JpaTransactionManagerbean。現在這會導致 JOOQ 自動配置拋出多個 DataSourceTransactionManager bean 存在例外。經過多次試驗和錯誤,對我有用的是:
private final TransactionAwareDataSourceProxy dataSource;
public DslConfig(DataSource dataSource) {
// A transaction aware datasource is needed, otherwise the spring @Transactional is ignored and updates do not work.
this.dataSource = new TransactionAwareDataSourceProxy(dataSource);
}
@Bean("transactionManager")
public PlatformTransactionManager transactionManager() {
// Needed for jpa transactions to work
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
請注意,我正在使用 aJpaTransactionManager但將 the 設定datasource為TransactionAwareDataSourceProxy。需要進一步測驗,但看起來 JPA 和 JOOQ 交易現在都在作業。
uj5u.com熱心網友回復:
需要注意的一件事是確保您使用的是正確的@Transactional注釋。在我的專案中有兩個:一個來自 Jakarta 包,一個來自 Spring 包——確保您使用的是 Spring 注釋。
我不知道你的Spring配置是否正確。我們使用 Java 配置,因此很難比較。
一個明顯的區別是我們有一個顯式的TransactionManager定義,這是您可能需要做的事情嗎?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/537464.html
