当前位置: 首页 > 面试题库 >

回滚@Transactional带注释的方法

沈飞舟
2023-03-14
问题内容

美好的一天。如下代码:

 class A{
     private B b;
    @Transactional
    public SomeResult doSomething(){
        SomeResult res = null;
        try {
          // do something 
        } catch (Exception e) {
            res  = b.saveResult();
        }
        return res ;
    }
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
class B{
  public SomeResult saveResult(){
      // save in db 
  }
}

据我了解,如果方法中存在异常,doSomething则不会回滚事务。以及如何使它滚动?并返回SomeResult


问题答案:

您不应该以编程方式调用回滚。根据docs的建议,最好的方法是使用声明性方法。为此,您需要注释哪些异常将触发回滚。

在你的情况下,像这样

@Transactional(rollbackFor={MyException.class, AnotherException.class})
public SomeResult doSomething(){
   ...
}

看一下@Transaction
API
和有关回滚事务的文档。

如果尽管有文档建议,但仍要进行程序化回滚,则需要TransactionAspectSupport按照已建议的方式进行调用。这是从文档:

public void resolvePosition() {
  try {
    // some business logic...
  } catch (NoProductInStockException ex) {
    // trigger rollback programmatically
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  }
}

但是可能存在架构错误。如果您的方法失败并且需要引发异常,则不应期望它返回任何内容。也许您对这种方法负有太多责任,应该创建一个仅对数据建模的单独方法,如果出现问题则抛出异常,从而回滚事务。无论如何,请阅读文档。



 类似资料:
  • 问题内容: 我已成功将此注释用于Dao类。回滚适用于测试。 但是现在我需要回滚真实代码,而不仅仅是测试。有用于测试的特殊注释。但是哪些注释适用于非测试代码?对我来说这是一个大问题。我已经花了一天的时间。官方文档不符合我的需求。 employeeDao is 这是一个注释可以很好地运行的测试: HibernateDaoBeans.xml 是的,我回滚了交易。我刚刚为服务添加了BEAN …,然后注释@

  • 我对事务REST控制器中的一些异常处理感到困惑。 我有一个管理服务,看起来像: 我有一个REST控制器,看起来像: 它使用@Transactional(readOnly = true)注释。 如果存在此注释并且没有找到搜索的项目,则它会给出以下异常: 如果删除注释,则一切正常,响应包含搜索的项。 我假设当没有找到搜索的条目时会抛出一个异常,触发事务回滚消息。 以下是异常处理程序: 有没有办法在日志

  • 问题内容: 我在Service类中看到了一种被标记为的方法,但是它也在同一类中调用了其他未标为的方法。 这是否意味着对单独方法的调用导致应用程序打开与DB的单独连接或暂停父事务等? 不带任何注释的方法的默认行为是什么,而另一个带有注释的方法调用该方法的默认行为是什么? 问题答案: 当你调用没有事务块之内的方法时,父事务将继续使用新方法。它将使用与父方法(with )相同的连接,以及在调用的方法中导

  • 我正在使用带有webflux的spring boot 2.4.2连接到postgres数据库。我在使用事务性代码时观察到了一个我不理解的行为。 为了展示这种行为,我创建了一个示例应用程序,试图将行添加到两个表中;表“a”和表“b”。对表“a”的插入预计将失败,并出现重复密钥冲突。考虑到使用了事务性,我希望不会向表“b”中添加任何行。 然而,根据我用哪个方法注释事务,我会得到不同的结果。 如果我对c

  • 在spring boot annotate中使用@Transactional从控制器调用update(),此update()调用update2()。所以,当我尝试使用update2()将重复值保存到数据库中时,它不会向update()抛出异常,而是转到控制器方法。我想在update()中处理异常。