首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >直到事务使用PlatformTransactionManager完成后才提交插入

直到事务使用PlatformTransactionManager完成后才提交插入
EN

Stack Overflow用户
提问于 2020-02-13 20:50:51
回答 1查看 2.1K关注 0票数 0

我需要确保在执行存储过程期间提交插入。使用Spring数据JPA1.5,这是JpaTransactionManager的默认行为。使用SpringBoot2.x,在存储过程完成执行之前不会提交插入。

因此,使用SpringBoot2.x事务mgmt调用此存储过程,在1分钟后不会插入:

代码语言:javascript
复制
CREATE procedure [dbo].[test_insert]
as
begin
    insert into myTempTable(col1)
    values ("1");

    WAITFOR DELAY '00:01';
end
GO

但是使用Spring 1.5事务mgmt调用它,将立即插入,这正是我所需要的。

这是密码。交易经理:

代码语言:javascript
复制
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory);
    return transactionManager;
} 

回购:

代码语言:javascript
复制
public interface TestRepository extends Repository<String, Long> {

    @Procedure("test_insert")
    void testInsert();

}

测试用例:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional(transactionManager="transactionManager")
public class InsertRepositoryTest {

    @Autowired
    private TestRepository testRepo;

    @Test
    public void testInsert() throws SQLException {
        testRepo.testInsert();
    }   

}

我使用的是Server 2016,它的默认事务级别设置为READ。

如何确保在执行过程中立即提交存储过程中的插入?

更新

经过更多的研究,我发现对于Spring的事务管理器,我处于隐式事务模式。但当我不使用它的时候,我就会自动提交。换句话说,select @@OPTIONS & 2用Spring的事务管理器返回2,没有它的0返回。因此,我认为这解释了为什么我看到了插入提交时间上的差异。如果这是正确的,那么我只需要知道如何设置自动提交。默认模式必须在Spring或Server驱动程序中更改(我使用4.2,现在使用8.2.0.jre 8)。

更新2

为什么在存储过程完成之前,其他一些进程能够看到插入到mytempTable很重要?因为在生产存储过程中,它执行插入、调用某个服务(我相信该服务从该行中选择数据并将数据插入到另一个表中),然后将sp waitfor数据显示在服务插入的表中。因此,在服务看不到insert的情况下,存储过程挂起,等待服务在另一个表中插入。

我认为解决方案是不使用显式事务,而只是让Server默认自动提交。不幸的是,这也意味着如果存储过程中有问题,就不会回滚。但是,考虑到存储过程和服务是第三方组件,我无法更改它们,我认为这是我唯一的选择。仍然想知道为什么SpringBoot1.5和2.x或JDBC驱动程序之间的行为是不同的。

更新3

结果表明,SpringBoot1.5和2.x或JDBC驱动程序版本之间的行为没有区别。也就是说,直到事务完成之后,插入才会发生。我之所以观察到行为上的差异,是因为我在一个旧项目中使用Spring 1.5进行测试,而旧项目是一个复合项目,有两个数据源和两个事务管理器,与我的Spring 2.x项目不同。不知道为什么或什么会使插入立即发生在旧的项目,但它做到了。

无论如何,查看Server日志,我可以确认,无论Spring / JDBC版本如何,当自动提交模式启动时,它都会立即插入。

EN

回答 1

Stack Overflow用户

发布于 2020-02-14 16:05:51

如果执行存储过程遵循标准实体操作的“事务写入”模式,则通常的行为是将SQL语句排队,直到事务完成为止。

缺省情况下,Spring数据存储库是事务性的,因此即使在测试中没有显式的@Transactional(transactionManager="transactionManager"),事务也在运行。

https://vladmihalcea.com/a-beginners-guide-to-jpahibernate-flush-strategies/ (假设您在这里使用Hibernate,但在其他JPA实现中可能有类似的概念)。

尝试此操作以触发立即刷新:

代码语言:javascript
复制
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional(transactionManager="transactionManager")
public class InsertRepositoryTest {

    @Autowired
    private TestRepository testRepo;

    @PersistenceContext 
    primate EntityManager em;

    @Test
    public void testInsert() throws SQLException {
        testRepo.testInsert();
        em.flush(); //write all buffered SQL statements
    }   
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60216257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档