我在哪里可以使用@Transactional

时间:2015-07-09 16:41:46

标签: spring spring-transactions

有人可以解释一下为什么会这样做:

@Transactional
@Test
public void test() {
    save();
}
public void save() {
    Scenario scenar = new Scenario();
    sessionFactory.getCurrentSession().save(scenar);
}

这不会,因为它找不到交易:

@Test
public void test() {
    save();
}
@Transactional
public void save() {
    Scenario scenar = new Scenario();
    sessionFactory.getCurrentSession().save(scenar);
}

谢谢!

2 个答案:

答案 0 :(得分:2)

Spring @Transactional注释使用Spring AOP。这意味着,当包含带有该注释的方法的bean被注入为不同bean的依赖项时,它将被包装在代理中。此代理具有与bean相同的接口,但在调用方法之前执行其他操作(在此情况下将其包装在事务中)。你可以把它想象成一种decorator。您甚至可以在调试应用程序时看到调用的代理。

现在,当从同一个类调用使用@Transactional注释的方法时,没有(至少不容易)注入代理的方法。没有办法替换&#34引用的对象;这个" Java中的关键字。

More reading on Spring AOP proxies

答案 1 :(得分:2)

由于您的方法注释为@Test,我认为这是Junit Test类的一部分。

Spring开发人员知道测试方法通常不实现接口,因此不能支持JDK代理。因此,他们特别支持@Transactional方法上的@Test注释doc说:

启用和禁用交易

使用@Transactional注释测试方法会导致测试在一个事务中运行,默认情况下,该事务将在测试完成后自动回滚。如果测试类使用@Transactional注释,则该类层次结构中的每个测试方法都将在事务中运行。未使用@Transactional注释的测试方法(在类或方法级别)将不会在事务中运行。此外,使用@Transactional注释但传播类型设置为NOT_SUPPORTED的测试将不会在事务中运行。