【问题标题】:Spring-JDBC batchUpdate is not committing changes. Is this a knwon bug?Spring-JDBC batchUpdate 没有提交更改。这是一个已知的错误吗?
【发布时间】:2014-07-30 09:36:40
【问题描述】:

我正在处理的项目使用以下依赖项

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>3.2.0.RELEASE</version>
 </dependency>

有了这个,我正在执行以下 方法调用 (1)

template.batchUpdate(INSERT_SQL, instance of BatchPreparedStatementSetter);

看Spring JDBCTemplate中的源码好像是(因为驱动支持 批量更新)调用 PreparedStatement 上的 executeBatch()。但是,我没有看到数据库中更新的影响。

这是一个真正的错误还是我在这里遗漏了明显的错误?如果这个问题已经解决,请告知一个好的版本。 请注意,我需要一个不依赖于其他 Spring 模块(例如 Spring Core 或 MVC)的版本。提前致谢。

【问题讨论】:

  • 这并不完全正确 - 它确实投票删除了此内容。
  • 我已经更新了我原来的问题 - 它确实清理了参数并将连接释放回执行()方法中的池。但是,我没有看到任何提交。是否要求我的数据源必须促进自动提交设置为 true 的连接?
  • 您确定打开一个非只读事务吗?我在更新没有影响时遇到的最后一个问题是由于“在视图模式中打开会话”提供的只读事务,并且没有明确的读写事务。
  • 我想您指的是在连接级别将 autocommit 设置为 true - 不,我反对它(不是严格意义上的,但在大多数情况下)。
  • 不,我不是指自动提交,而是指显式事务管理(@Transactional 注释,PlatformTransactionManager

标签: java spring commit spring-jdbc batch-updates


【解决方案1】:

如果你不想使用自动提交,你必须在你的 Spring 配置中设置一个PlatformTransactionManager。对于简单的 JDBC 使用,您可以使用 DataSourceTransationManager

在 web 应用程序中,在服务层使用@Transactional 注释是很常见的。在一个简单的应用程序中,Spring 提出了TransactionTemplate。这是 Spring 参考手册 3.2 中的一个示例

public class SimpleService implements Service {

  // single TransactionTemplate shared amongst all methods in this instance
  private final TransactionTemplate transactionTemplate;

  // use constructor-injection to supply the PlatformTransactionManager
  public SimpleService(PlatformTransactionManager transactionManager) {
    Assert.notNull(transactionManager, "The 'transactionManager' argument must not be null.");
    this.transactionTemplate = new TransactionTemplate(transactionManager);
  }

  public Object someServiceMethod() {
    return transactionTemplate.execute(new TransactionCallback() {

      // the code in this method executes in a transactional context
      public Object doInTransaction(TransactionStatus status) {
        updateOperation1();
        return resultOfUpdateOperation2();
      }
    });
  }
}

updateOperation 是必须在事务上下文中调用的方法。

【讨论】:

  • 谢谢谢尔盖。 +1 表示您花在提供此详细答案上的时间。我已经从docs.spring.io/spring/docs/3.0.x/spring-framework-reference/… 了解了 Spring 事务管理。我想我的问题的答案是:不,这是不可能的。我认为 JDBCTemplate 更新操作背后的理念是提交/回滚/事务上下文传播需要分离 - 但是我投票赞成 JDBCTemplate 不应该做出这种假设的想法。如果是这样,那么更新不应成为其提供的服务的一部分。无论如何..谢谢。
【解决方案2】:

1) 您的事务管理设置/配置是什么? 2) 你如何开始和提交交易?您是否在任何方法调用周围都有 @Transactional 注释?例如

@org.springframework.transaction.annotation.Transactional
public void doUpdate() {
  // jdbc template calls go here...
}

【讨论】:

  • spring.jdbc 未在此处的任何事务上下文中使用。选择此模板是为了利用 RowMapper 和其他人的强大功能,但是,您似乎必须将代码放在事务上下文中为了将任何东西提交到数据库并且无法自行管理?
  • 您可以自己管理它,您必须将事务管理器注入您的代码,然后手动开始/提交事务。我从来没有使用过这种方法,没有代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
相关资源
最近更新 更多