当前位置: 首页 > 知识库问答 >
问题:

有@Transactional(propagation=propagation.SUPPORTS)的方法和没有@Transactional的方法有什么区别?

曾永新
2023-03-14

方法和方法有什么区别

@Transactional(propagation = Propagation.SUPPORTS)

和一个没有@事务性的方法?

例如:

public class TEst {

    @Transactional
    public void methodWithTransaction1(){
        methodWithSupportsTransaction();
    }

    @Transactional
    public void methodWithTransaction2(){
        methodWithoutTransactional();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public void methodWithSupportsTransaction(){

    }

    public void methodWithoutTransactional(){

    }
}

共有2个答案

堵琨
2023-03-14

Spring支持两种类型的事务管理:编程式和声明式。

编程事务管理:以这种方式,事务需要由我们处理。比如说-

EntityTransaction tran = entityManager.getTransaction(); 
try { 
    tran.begin(); 
    methodWithoutTransactional();
    tran.commit(); 
} catch(Exception ex) { 
    tran.rollback(); 
    throw ex; 
}

声明性事务管理:通过这种方式,我们可以通过使用注释或基于xml的配置将事务管理代码从业务逻辑中分离出来。您已经在示例代码中完成了-

@Transactional
public void methodWithTransaction1(){
    methodWithSupportsTransaction();
}

对于@Transactional annotation,如果我们不定义传播类型,默认情况下将应用需要的传播。您可以在这里找到文档。

羊舌洛华
2023-03-14

除了javadoc中指出的关于同步的细微差异外,两者之间的区别在于,如果方法被注释为transactional,事务代理将拦截该方法调用,并且仅当从该方法引发运行时异常时,才会将当前事务(如果有)标记为回滚。

那么,让我们举个例子:

public class A {
    @Autowired B b;

    @Transactional
    public void foo() {
        try {
            b.bar();
        }
        catch (RuntimeException e) {
            // ignore
        }

        ...
    }
}

public class B {
    // @Transactional(propagation = Propagation.SUPPORTS)
    public void bar() {
        throw new RuntimeException();
    }
}

调用a.foo()将在不存在事务时启动事务(需要传播)。然后将调用b.bar()并引发异常。异常被a.foo()捕获,它继续执行,就像什么都没发生一样。在a.foo()的末尾,事务将被成功提交。

现在让我们取消对b.bar()的Transactional注释。如果事务还不存在,调用a.foo()将启动事务(需要传播)。然后将调用b.bar()并抛出异常。此异常将被B周围的事务代理“拦截”,该代理将事务标记为rollback Only。然后异常将传播到A.a.foo()。异常被a.foo()捕获,它继续执行,就像什么都没发生一样。在a.foo()的末尾,事务将被提交,但该提交将失败,因为事务已被标记为rollback Only。a.foo()的调用方将获得一个TransactionSystemExcure。

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

  • 问题内容: 使用Spring(3.0.5),Hibernate(3.6.0)和Wicket(1.4.14)开发应用程序时遇到了一个奇怪的问题。问题是:我无法将任何对象保存或修改到数据库中。“不能”是指对象的所有更改或对EntityManager.persist(foo)的调用都被简单,无声地忽略。选择工作。 示例案例很简单-在某些检票页面上,我尝试将对象保存到数据库中,如下所示 这是comicDA

  • 问题内容: 如果有人可以解释此注释的作用以及确切的使用时间: 谢谢 问题答案: 当传播设置为PROPAGATION_REQUIRED时,将为应用该设置的每种方法创建一个逻辑事务作用域。每个此类逻辑事务作用域可以单独确定仅回滚状态,而外部事务作用域在逻辑上与内部事务作用域无关。当然,在标准PROPAGATION_REQUIRED行为的情况下,所有这些范围都将映射到同一物理事务。因此,内部事务范围中设

  • 问题内容: 有人可以通过实际示例解释注释中的隔离和传播参数吗? 基本上,何时和为什么我应该选择更改其默认值。 问题答案: 好的问题,尽管不是一个简单的答案。 Propagation 定义事务之间的关系。常用选项: :代码将始终在事务中运行。创建一个新事务或重用一个事务(如果有)。 :代码将始终在新事务中运行。如果存在当前事务,则将其挂起。 Isolation 定义事务之间的数据契约。 :允许脏读。

  • 问题内容: 在执行以下操作时,当我尝试访问延迟加载的异常时遇到错误: 我的实体看起来像这样: 我的印象是,通过在我的方法中使用@Transactional批注,它将使会话保持活动状态,直到该方法完成为止,从而使我可以访问延迟加载的Address集合。 我想念什么吗? 编辑 按照Tomasz的建议:在我的方法中,状态变为。 这确实可以缩小问题的范围,但是为什么此时我的“交易”不能处于活动状态? 问题