如何配置在 Spring + JDBC 中关闭自动提交?

Posted

技术标签:

【中文标题】如何配置在 Spring + JDBC 中关闭自动提交?【英文标题】:How can I config to turn off autocommit in Spring + JDBC? 【发布时间】:2012-03-27 19:18:50 【问题描述】:

我在使用 Spring 和 JDBC,发现它是自动提交的。

如何在 spring-servlet.xml 中配置将其关闭?

这是我当前的配置:

<bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
    p:driverClassName="$jdbc.driverClassName"
    p:url="$jdbc.databaseurl" p:username="$jdbc.username"
    p:password="$jdbc.password" />

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"/>
</bean>

【问题讨论】:

【参考方案1】:

您不能,只需在事务中运行您的代码,Spring 会自动为您禁用自动提交。在 Spring 的事务中运行一段代码的最简单(至少是设置)方法是使用 TransactionTemplate

TransactionTemplate template = new TransactionTemplate(txManager);

template.execute(new TransactionCallback<Object>() 
  public Object doInTransaction(TransactionStatus transactionStatus) 
    //ALL YOUR CODE ARE BELONG TO... SINGLE TRANSACTION
  

【讨论】:

感谢您的回答。为了支持更大的图景,似乎 Spring 为简单的 jdbc 创建了更多复杂性。 :) @SurasinTancharoen:嗯,不是真的。我说最容易设置,但不使用。使用 @Transactional 或 AOP,您可以在单个事务中运行多行代码,而对代码的更改最少。 我刚刚阅读了这个ibm.com/developerworks/java/library/j-ts2/index.html“使用 Spring 进行程序化事务”可以替代吗? 另外,我发现了有关 org.springframework.transaction.interceptor.TransactionProxyFactoryBean 的信息,请参阅此处nerdnotes.wordpress.com/2007/03/30/…。它可以是另一种选择吗?【参考方案2】:

试试 defaultAutoCommit 属性。代码如下所示:

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="$jdbc.driverClassName"
p:url="$jdbc.databaseurl" p:username="$jdbc.username"
p:password="$jdbc.password"
p:defaultAutoCommit="false" />

查看javadoc: http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html#defaultAutoCommit

【讨论】:

【参考方案3】:

看来我的配置漏掉了这一行:

<tx:annotation-driven transaction-manager="txManager"/>

然后,在我的服务类中,我使用@Transactional 注释。例如

@Service
class CompanyServiceImpl implements CompanyService
    @Autowired
    private CompanyDAO companyDAO;

    @Transactional
    public void addCompany(Company company) 
            companyDAO.addCompany(company); // in here, there is JDBC sql insert
            companyDAO.addCompany_fail(company); // just for test
    

如果 addCompany_fail() 发生异常,第一个 addCompany() 也将被回滚。

我按照这个文档来了解 Spring 中事务是如何控制的。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html

我按照此文档了解如何在 Spring 中使用 JDBC 进行编码。 http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jdbc.html

我也读过这个(免费)http://www.infoq.com/news/2009/04/java-transaction-models-strategy。它真的很好。而且我对大多数人不了解(或不关心)交易的作者也有同样的感觉。

PS: 似乎很多人误解了使用这样的 Hibernate/Spring 框架只是为了避免 JDBC 和事务控制的复杂性。许多人认为“JDBC 和 Transaction 太复杂了,只需使用 Hibernate 而忽略这两个”。网上很多关于 Spring+Hibernate 或 Spring+JDBC 的例子似乎根本不关心事务。我觉得这是一个糟糕的笑话。交易太严肃了,不真正理解就任凭事情处理。

Hibernate 和 Spring 是如此强大和如此复杂。然后,正如有人所说,“权力伴随着责任”。

更新:2013-08-17:这里有很好的关于交易的例子http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial。但是,这并不能解释如果你想使用 REQUIRES_NEW,为什么你需要创建另一个类(否则你会得到这个问题Spring Transaction propagation REQUIRED, REQUIRES_NEW,它似乎 REQUIRES_NEW 并没有真正创建一个新事务)

更新:2018-01-01:我在 https://www.surasint.com/spring-boot-database-transaction-jdbi/ 处创建了一个带有 Spring Boot 1.5.8.RELEASE 的完整示例 还有一些基本的实验例子在这里https://www.surasint.com/spring-boot-connection-transaction/

【讨论】:

这行得通,因为 Spring 事务管理器关闭了自动提交并自己提交?

以上是关于如何配置在 Spring + JDBC 中关闭自动提交?的主要内容,如果未能解决你的问题,请参考以下文章

使用 try-with-resources 或在“finally”子句中关闭此“PreparedStatement”。在 Spring JDBC [重复]

在 JDBC 中关闭后 Postgresql 连接保持空闲

如何在 Spring Security 中关闭 HTTP 会话超时?

如何在 Spring Boot 应用程序中关闭 Spring Security

使用simplejdbccall时如何在spring中关闭refcursor

如何在我的新 Spring Boot 项目中关闭 Spring Security?