現在、以下のようにプロパティをデータソースBean IDに追加することにより、春にautocommitをfalseに設定しています:
<property name="defaultAutoCommit" value="false" />
しかし、プロシージャを実行する前に、単一のJavaメソッドに具体的に追加する必要があります。以下のコードスニペットを使用しました。
getJdbcTemplate().getDataSource().getConnection().setAutoCommit(false);
しかし、上記の行は自動コミットをfalseに設定していませんでしたか?
何か不足していますか?
または特定のJava springによるメソッドで自動コミットを設定する代替手段
ありがとう
問題は、Connection
で自動コミットを設定しているが、JdbcTemplate
はConnection
を覚えていないことです。代わりに、各操作に対して新しいConnection
を取得します。これは、Connection
実装に応じて、同じDataSource
インスタンスである場合とそうでない場合があります。 defaultAutoCommit
はDataSource
のプロパティではないため、2つのオプションがあります。
defaultAutoCommit
のセッター(たとえば、 org.Apache.commons.dbcp.BasicDataSource )があると仮定して、DataSource
を具象実装にキャストします。もちろん、これは、Spring構成でDataSource
を変更できないことを意味します。これは、依存性注入の目的に反します。((BasicDataSource)getJdbcTemplate().getDataSource()).setDefaultAutoCommit(false);
接続を取得するたびにAutoCommitをfalseに設定するラッパー実装にDataSource
を設定します。
final DataSource ds = getJdbcTemplate().getDataSource();
getJdbcTemplate().setDataSource(new DataSource(){
// You'll need to implement all the methods, simply delegating to ds
@Override
public Connection getConnection() throws SQLException {
Connection c = ds.getConnection();
c.setAutoCommit(false);
return c;
}
});
現在の接続を取得する必要があります。例えば.
Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
try {
conn.setAutoCommit(false);
/**
* Your Code
*/
conn.commit();
} catch (SQLException e) {
conn.rollback();
e.printStackTrace();
}
私はこれに出くわし、解決策は手遅れになっても誰かを助けるだろうと考えました。
Yosefが言ったように、getJdbcTemplate().getDataSource().getConnection()
メソッドを呼び出して取得する接続は、操作のためのデータベースとの通信に使用される接続である場合とそうでない場合があります。
代わりに、データをコミットするのではなく、スクリプトをテストするだけでよい場合は、自動コミットをフォールトに設定したApache Commons DBCPデータソースを使用できます。 Beanの定義は次のとおりです。
/**
* A datasource with auto commit set to false.
*/
@Bean
public DataSource dbcpDataSource() throws Exception {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
ds.setDefaultAutoCommit(false);
ds.setEnableAutoCommitOnReturn(false);
return ds;
}
// Create either JdbcTemplate or NamedParameterJdbcTemplate as per your needs
@Bean
public NamedParameterJdbcTemplate dbcpNamedParameterJdbcTemplate() throws Exception {
return new NamedParameterJdbcTemplate(dbcpDataSource());
}
そして、このような操作にはこのデータソースを使用します。
トランザクションをコミットする場合は、自動コミットをデフォルトの動作であるtrue
に設定したデータソースのBeanをもう1つ用意することをお勧めします。
それが誰かを助けることを願っています!
JdbcTemplateが実行するステートメントごとに実行する必要があります。 jdbcTemplate.execute()などごとに、データソースの接続プールから新しい接続を取得するためです。そのため、jdbcTemplateがそのクエリに使用する接続用に設定する必要があります。だからあなたは次のようなことをしなければなりません
jdbcTemplate.execute("<your sql query", new PreparedStatementCallback<Integer>(){
@Override
public Integer doInPreparedStatement(PreparedStatement stmt) throws SQLException, DataAccessException
{
Connection cxn = stmt.getConnection();
// set autocommit for that cxn object to false
cxn.setAutoCommit(false);
// set parameters etc in the stmt
....
....
cxn.commit();
// restore autocommit to true for that cxn object. because if the same object is obtained from the CxnPool later, autocommit will be false
cxn.setAutoCommit(true);
return 0;
}
});
お役に立てれば
場合によっては、単に@Transactional
メソッド内、たとえばバッチ挿入の後、最後にコミットを実行します。
私はこれをどこでも探していたので投稿しています:Springブートの設定プロパティを使用して、デフォルトの自動コミットモードを次のように設定しました:
spring.datasource.hikari.autocommit: false