Actuellement, je mets autocommit à false au printemps en ajoutant une propriété à un identifiant de bean source de données, comme ci-dessous:
<property name="defaultAutoCommit" value="false" />
Mais j’ai besoin de l’ajouter spécifiquement à une seule méthode Java avant d’exécuter ma procédure ..__ J'ai utilisé le fragment de code ci-dessous.
getJdbcTemplate().getDataSource().getConnection().setAutoCommit(false);
Mais la ligne ci-dessus ne définissait pas autocommit sur false?
Est-ce que je manque quelque chose?
ou n’importe quelle alternative pour définir autocommit dans une méthode Java spécifique avant le printemps
Merci
Le problème est que vous définissez autocommit sur une Connection
, mais JdbcTemplate
ne se souvient pas que Connection
; au lieu de cela, il obtient une nouvelle Connection
pour chaque opération et il peut s'agir ou non de la même instance Connection
, en fonction de votre implémentation DataSource
. Puisque defaultAutoCommit
n'est pas une propriété sur DataSource
, vous avez deux options:
defaultAutoCommit
(par exemple, org.Apache.commons.dbcp.BasicDataSource ), transformez la DataSource
en votre implémentation concrète. Bien entendu, cela signifie que vous ne pouvez plus modifier votre DataSource
dans votre configuration Spring, ce qui irait à l’encontre de l’injection de dépendance.((BasicDataSource)getJdbcTemplate().getDataSource()).setDefaultAutoCommit(false);
Définissez la variable DataSource
sur une implémentation d'encapsuleur définissant AutoCommit sur false à chaque extraction d'une connexion.
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;
}
});
Je viens de découvrir cela et je pensais que la solution aiderait quelqu'un même s'il est trop tard.
Comme l'a dit Yosef, la connexion obtenue en appelant la méthode getJdbcTemplate().getDataSource().getConnection()
peut être ou non celle utilisée pour la communication avec la base de données pour votre opération.
Si vous souhaitez simplement tester votre script et non pas valider les données, vous pouvez utiliser une source de données Apache Commons DBCP avec la validation automatique définie. La définition du haricot est donnée ci-dessous:
/**
* 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());
}
Et utilisez cette source de données pour de telles opérations.
Si vous souhaitez valider vos transactions, je vous suggère d’avoir un bean supplémentaire de la source de données avec la validation automatique définie sur true
, qui correspond au comportement par défaut.
J'espère que ça aide quelqu'un!
Vous devrez faire pour chaque instruction exécutée par jdbcTemplate. Parce que pour chaque jdbcTemplate.execute () etc., il obtient une nouvelle connexion à partir du pool de connexions de la source de données. Vous devrez donc le définir pour la connexion que la connexion utilisée par jdbcTemplate pour cette requête. Donc, vous devrez faire quelque chose comme
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;
}
});
J'espère que cela t'aides
Vous devez obtenir la connexion actuelle. par exemple.
Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
try {
conn.setAutoCommit(false);
/**
* Your Code
*/
conn.commit();
} catch (SQLException e) {
conn.rollback();
e.printStackTrace();
}