Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在类上定义@Transactional与在方法上定义@Transactional有什么区别 案例1 案例2_Java_Spring_Spring Mvc_Spring Transactions - Fatal编程技术网

Java 在类上定义@Transactional与在方法上定义@Transactional有什么区别 案例1 案例2

Java 在类上定义@Transactional与在方法上定义@Transactional有什么区别 案例1 案例2,java,spring,spring-mvc,spring-transactions,Java,Spring,Spring Mvc,Spring Transactions,在案例1中,如果发生任何异常,则回滚工作,但在案例2中,它不工作。如果我遵循案例1,是否存在任何性能问题?引用 Spring团队的建议是只使用@Transactional注释具体类,而不是注释接口 由于该机制基于代理,因此只有通过代理传入的“外部”方法调用才会被拦截。这意味着“自调用”,即目标对象中调用目标对象的其他方法的方法,即使调用的方法标记为@Transactional,也不会在运行时产生实际的事务 类上的@Transactional应用于服务上的每个方法。这是一条捷径。通常,如果您知道所

在案例1中,如果发生任何异常,则回滚工作,但在案例2中,它不工作。如果我遵循案例1,是否存在任何性能问题?

引用

Spring团队的建议是只使用@Transactional注释具体类,而不是注释接口


由于该机制基于代理,因此只有通过代理传入的“外部”方法调用才会被拦截。这意味着“自调用”,即目标对象中调用目标对象的其他方法的方法,即使调用的方法标记为@Transactional,也不会在运行时产生实际的事务

类上的
@Transactional
应用于服务上的每个方法。这是一条捷径。通常,如果您知道所有方法都将访问存储库层,则可以在服务类上设置
@Transactional(readOnly=true)
。然后,您可以在模型中执行更改的方法上使用
@Transactional
覆盖该行为。1)和2)之间的性能问题未知。

假设您有以下类:

@Transactional(readOnly = true)
public class DefaultFooService implements FooService {

  public Foo getFoo(String fooName) {
    // do something
  }

  // these settings have precedence for this method
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public void updateFoo(Foo foo) {
    // do something
  }
}
类级别上的
@Transactional
注释将应用于类中的每个方法

但是,当使用
@Transactional
(如
updateFoo(Foo-Foo)
)注释方法时,这将优先于在类级别定义的事务设置

更多信息:


在案例1中@Transactional应用于每个公共的单个方法。Spring忽略私有和受保护的方法

Spring将类级注释应用于 我们没有用@Transactional注释的这个类。然而,如果 我们将注释放在私有或受保护的方法上,Spring将 忽略它而不出错

在案例2中@Transactional仅应用于method2(),而不应用于method1()

案例1: -调用method1()->事务已启动。method1()调用method2()时,不会启动新事务,因为已经有一个事务

案例2: -调用method1()->未启动任何事务。method1()调用method2()时,不会启动新事务。这是因为@Transactional在从同一类中调用方法时不起作用。如果您从另一个类调用method2(),它将起作用

从:

在代理模式(这是默认模式)下,只截获通过代理传入的外部方法调用。这意味着自调用,实际上是目标对象内调用目标对象另一个方法的方法,即使调用的方法标记为@Transactional,在运行时也不会导致实际事务。此外,代理必须完全初始化以提供预期的行为,因此您不应在初始化代码中依赖此功能,即@PostConstruct


这并没有指出
@Transactional
带注释的方法和
@Transactional
带注释的类之间的区别。@kocko>我以为OP会跟随链接,但我刚刚更新了我的答案,请看一看。@mok我面临的是“自我调用不会创建事务”这个问题和答案让我想起了我以前学到的东西。非常感谢。这并不能解释OP所要求的区别,只是强调了一个用
@Transactional
注释方法的问题。链接的文档现在已更新。为了子孙后代的利益,最新的文档说:Spring团队建议您只使用@Transactional注释具体类(以及具体类的方法),而不是注释接口。但只有在外部调用updateFoo时才这样做。如果getFoo调用updateFoo(如OP ask),那么整个事务将是只读的。如果警告从非注释方法调用注释方法,则加倍:它不会启动事务,即使对于注释方法也是如此。另请参见mok的回答。如果我注释一个类Transactional(value=“notPrimaryTransactionManager”),然后用Transactional(readOnly=true)注释一个成员方法,该方法会使用“notPrimaryTransactionManager”还是使用spring提供的默认事务管理器?
public class UserServiceImpl implements UserService {

    ...................
    public void method1(){
        try{
            method2();
        }catch(Exception e){

        }
    }
    @Transactional
    public void method2(){

    }
}
@Transactional(readOnly = true)
public class DefaultFooService implements FooService {

  public Foo getFoo(String fooName) {
    // do something
  }

  // these settings have precedence for this method
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public void updateFoo(Foo foo) {
    // do something
  }
}