在 spring 引导应用程序中将多个调用包装在一个事务中?

wrapping multiple calls in a transaction in spring boot application?

我正在使用 jdbctemplate 在我的 spring 应用程序中对数据库执行查询。

这里是用@Transactional注解的方法

@Transactional
public boolean doSomething(){    
    try {
        jdbcTemplate.update(sql1); //1
        jdbcTemplate.update(sql2); //2
        jdbcTemplate.update(sql3); //3
        return true; 
    } catch (Exception ex){
        return false;
    }
}

我的问题是,如果1和2成功,3失败,1和2上的事务会回滚吗?我该如何测试?

此外,使用布尔值作为 return 值是否是指示事务状态的良好做法?

如果3失败,1和2会回滚。这是事务(工作单元)的核心点。
基于@Zergleb 的回答的重要更正:仅当您抛出异常时。在您的代码中,您正在处理异常,因此 1 和 2 将持续存在,因为事务没有 "see" 异常,它不知道有什么问题。

为了测试,在 sql3 中放入一些无效的 sql,看看会发生什么。

我通常不会 return 布尔值来表示成功。 Success 是该方法的成功完成,如果您的场景指示这样,您应该让异常冒泡或将异常包装在更合适的东西中并抛出它。

例如:

@Transactional
public void doSomething(){
    try {
        jdbcTemplate.update(sql1); //1
        jdbcTemplate.update(sql2); //2
        jdbcTemplate.update(sql3); //3
    } catch (Exception ex){
        throw new MyCustomPersistenceException("Could not doSomething", e);
    }
}

如果1和2成功,3失败,1和2上的事务会回滚吗?

如果第三次操作失败,将回滚第一次和第二次操作。但如果它们是同一事务或事务上下文的一部分。

例如,如果您将事务管理器定义为 DataSourceTransactionManager,它将回滚同一连接的 JDBC 操作。在您的情况下,您在同一个方法中执行了所有三个操作并且使用了相同的 jdbcTemplate,因此它将回滚您的其他两个事务。

如果使 sql 指令失败,您可以对此进行测试,例如:

  1. 插入正确
  2. 插入正确
  3. INSERT 但您可以尝试在数字列中插入字符串,或在非空列中插入空值。

你可以在这里看到更多 http://www.journaldev.com/2603/spring-transaction-management-jdbc-example

http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html

关于返回boolean我觉得还是抛异常比较好,会自动回滚事务

不!如果您捕获异常,您的 sql 将不会回滚!!!!

这不会触发回滚。您需要删除 try-catch。但是,是的,如果抛出运行时异常,这些将按预期回滚。请参考以下文档。

@Transactional settings

http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html#transaction-declarative-attransactional-settings

您会看到下面的几行,回滚是由任何 RuntimeException 触发的。因此,如果您捕获到异常,它不会触发回滚,它只会在您 return false 时结束事务。进一步注意,如果你抛出一个已检查的异常,它不会回滚,所以不要试图通过抛出一个异常来解决这个问题,无论你打算用那个布尔值 return 值做什么。

我自己还没有尝试过,但是如果你在@Transactional 上设置 rollbackFor 属性 或者可能只是在这个方法的外部捕获 RuntimeException,你似乎可以回滚检查的异常?或者抛出你自己的运行时异常?我把它留给你。

如上所述,这也适用于存储库,您可以在此处查看示例

Spring Data(Repositories) transactions

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions