Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SpringJDBC模板中将autocommit设置为false_Spring_Spring Mvc_Spring Jdbc_Spring Transactions - Fatal编程技术网

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

如何在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不记得连接;相反,它为每个操作获取一个新的连接,该连接可能是相同的

目前,我正在spring中将autocommit设置为false,方法是向数据源bean id添加一个属性,如下所示:

   <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();