gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:28:34 25 4
gpt4 key购买 nike

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

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com