如何在SpringJDBC模板中将autocommit设置为false
目前,我正在spring中将autocommit设置为false,方法是向数据源bean id添加一个属性,如下所示:如何在SpringJDBC模板中将autocommit设置为false,spring,spring-mvc,spring-jdbc,spring-transactions,Spring,Spring Mvc,Spring Jdbc,Spring Transactions,目前,我正在spring中将autocommit设置为false,方法是向数据源bean id添加一个属性,如下所示: <property name="defaultAutoCommit" value="false" /> 但是上面的行没有将自动提交设置为false 我遗漏了什么吗 或者spring在特定java方法中设置自动提交的任何替代方法 谢谢问题是您正在连接上设置自动提交,但是JdbcTemplate不记得连接;相反,它为每个操作获取一个新的连接,该连接可能是相同的
<property name="defaultAutoCommit" value="false" />
但是上面的行没有将自动提交设置为false我遗漏了什么吗
或者spring在特定java方法中设置自动提交的任何替代方法
谢谢问题是您正在
连接上设置自动提交
,但是JdbcTemplate
不记得连接
;相反,它为每个操作获取一个新的连接
,该连接可能是相同的连接
实例,也可能不是相同的实例,具体取决于数据源
实现。由于defaultAutoCommit
不是DataSource
上的属性,因此有两个选项:
假设您的具体数据源有一个用于defaultAutoCommit
(例如,)的setter,则将datasource
强制转换为您的具体实现。当然,这意味着您不能再在Spring配置中更改数据源
,这违背了依赖注入的目的
((BasicDataSource)getJdbcTemplate().getDataSource()).setDefaultAutoCommit(false)代码>
将DataSource
设置为包装器实现,该实现在每次获取连接时将AutoCommit设置为false
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;
}
});
您需要获得当前连接。e、 g
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()
方法获得的连接可能是用于与数据库通信的连接,也可能不是
相反,如果您的需求只是测试脚本,而不是提交数据,那么可以将apachecommons DBCP数据源的auto commit设置为fault。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());
}
并将此数据源用于任何此类操作
如果您希望提交事务,我建议您将数据源的另一个bean的auto commit设置为true
,这是默认行为
希望它能帮助别人 对于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;
}
});
jdbcTemplate.execute(“在某些情况下,您可以在方法中添加@Transactional
,例如,在一些批插入之后,最后执行commit。我之所以发布这篇文章,是因为我到处都在寻找它:我在Spring boot中使用配置属性来实现设置默认的自动提交模式:
spring.datasource.hikari.auto-commit: false
5年后,这仍然是一个有效的问题,我通过以下方式解决了我的问题:
使用connection.setAutoCommit设置连接(false)
使用该连接创建jbc模板
做好你的工作,做出承诺
可能重复的()我知道可以通过数据源bean id的属性标记将autocommit设置为false。但是我不想这样设置。我想在java数据库业务逻辑中将autocommit设置为falsemethod@shirish:您提供的链接正在说明我已经做了什么..!为什么?如果使用事务管理器,默认情况下会禁用自动提交。您r方法不起作用,因为它会给你一个非托管连接(如果你运行这个x次,其中x是你池中的连接数,你的池将被耗尽)。@M.Denium。你能帮助我如何做到这一点,以及使用事务管理器的设置是什么吗如果commit()
抛出异常和cxn.setAutoCommit(真)
不执行?@broc.seib fair point,cxn.setAutoCommit(真)应该在finally块中,但我希望答案能够说明如何在jdbctemplate中将autocommit设置为false在获取result@Haider关于Oracle nope。保存点是在dml语句之前创建的。还请记住,在ddl stmt上发生了隐式提交。谢谢!这在我的spring引导中起到了作用projekt,而不是spring.datasource.auto commit=false!
spring.datasource.hikari.auto-commit: false
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
JdbcTemplate jdbcTemplate =
new JdbcTemplate(newSingleConnectionDataSource(connection, true));
// ignore case in mapping result
jdbcTemplate.setResultsMapCaseInsensitive(true);
// do your stuff
connection.commit();