如何在spring jdbc模板中将autocommit设置为false

bad*_*mer 22 spring spring-mvc spring-jdbc spring-transactions

目前我通过向数据源bean id添加属性来在spring中将autocommit设置为false,如下所示:

   <property name="defaultAutoCommit" value="false" /> 
Run Code Online (Sandbox Code Playgroud)

但是我需要在执行我的程序之前在一个java方法中专门添加它.我使用了下面的代码片段.

  getJdbcTemplate().getDataSource().getConnection().setAutoCommit(false);
Run Code Online (Sandbox Code Playgroud)

但上面的一行并没有将autocommit设置为false?
我错过了什么吗?
或者通过spring在特定java方法中设置autocommit的任何替代方法

谢谢

mof*_*tje 10

我发布这个是因为我到处寻找它:我在 Spring boot 中使用配置属性来实现设置默认自动提交模式:

spring.datasource.hikari.auto-commit: false
Run Code Online (Sandbox Code Playgroud)

Hikari 的 Spring Boot 2.4.x 文档


sol*_*ing 9

5年后仍然是一个有效的问题,我以这种方式解决了我的问题:

  1. 使用connection.setAutoCommit(false)设置连接;
  2. 使用该连接创建一个 jbc 模板;
  3. 做好你的工作并承诺。
    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();
Run Code Online (Sandbox Code Playgroud)


Yos*_*ner 8

问题是你在a上设置autocommit Connection,但是JdbcTemplate不记得了Connection; 相反,它Connection为每个操作获取一个新的,并且可能是也可能不是同一个Connection实例,具体取决于您的DataSource实现.由于defaultAutoCommit不是财产DataSource,您有两种选择:

  1. 假设您的具体数据源有一个setter defaultAutoCommit(例如,org.apache.commons.dbcp.BasicDataSource),请转换DataSource为您的具体实现.当然,这意味着您无法再更改DataSourceSpring配置,这会破坏依赖注入的目的.

((BasicDataSource)getJdbcTemplate().getDataSource()).setDefaultAutoCommit(false);

  1. 设置为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;
      }
    });
    
    Run Code Online (Sandbox Code Playgroud)


Pra*_*u R 7

您必须对 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;

        }
    });
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


小智 5

您需要获取当前连接。例如

Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
    try {
        conn.setAutoCommit(false);

        /**
         * Your Code
         */
        conn.commit();
    } catch (SQLException e) {
        conn.rollback();
        e.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)