java - Spring 什么时候不应该提交? (与 Oracle 自动提交相关)

标签 java oracle spring jdbc

我有一个像下面这样的界面

public interface FooDAO {
  public void callA(String x);
}

和下面的实现故意使 readonly 为真且不受支持

public class FooDAOImpl implements FooDAO {

  //for testing
  @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED) 
  public void callA(String x) {
     //sql update method
  }
}

在我的 spring 上下文中,我声明了数据源事务管理器和 tx:annotation-driven。我写了一个 Junit4 测试,看起来像

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(...)
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
public class MyTest {

    @Resource
    FooDAO fooDAO;

    @Test
    public void testRegisterWorker() {
        fooDAO.callA("")
    }
}

我本以为记录根本不会被插入到数据库中。但是我看到该行实际上已插入到数据库中。我确实使用 Oracle 数据库,所以我认为自动提交默认设置为 true(我认为)。但是 spring 交易标签不应该覆盖它们吗?

谁能告诉我这里出了什么问题?

最佳答案

自动提交可能是默认开启的。使用 DataSourceTransactionManager,只有 事务实际启动时才会更改自动提交。 NOT_SUPPORTED 或 SUPPORTS 都不会启动事务,因此连接处于的任何默认状态都将保持不变。

考虑在 Spring xml 文件中默认关闭自动提交。如果启用,Spring 将不得不在每次 tx 之前更改它并在之后恢复它,这在 Oracle 中可能是昂贵的(不确定)。这也可以防止您意外地在事务之外提交。

有关详细信息,请参阅 org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(),它管理连接的自动提交和隔离级别。如果传播是 REQUIRED、REQUIRES_NEW 或 PROPAGATION_NESTED,doBegin() 仅由 AbstractPlatformTransactionManager.getTransaction()handleExistingTransaction() 调用。


您可能想看看 org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests。这是一个可用于测试类的 Spring 感知基类。它将在每个测试用例结束时回滚任何事务。这样就不需要为了测试而更改注释。您可以将 @Transactional 设置为它们应该在产品中的方式,并依靠回滚来确保在测试期间数据库中没有任何实际更改。

关于java - Spring 什么时候不应该提交? (与 Oracle 自动提交相关),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3110750/

相关文章:

Java Regex matches() 返回 false 但在浏览器中有效

java - 使用状态模式获取具有特定状态的对象

oracle - Azure 逻辑应用 - Oracle 连接器 - 执行查询

xml - 如何在 Spring MVC 中配置自定义 MediaType?

java - 如何创建两个边框

java - Objective-C 相当于 Java 枚举或 "static final"对象

sql - Oracle SUM 返回错误的摘要,其中包含从 SELECT UNION 返回的相同值

sql - 将表中的多行分组到列中

java - Spring资源事务管理

Spring @cachable——查看缓存数据