春天和@transactional,这是正常的? [英] spring and @transactional, is this normal?

查看:106
本文介绍了春天和@transactional,这是正常的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了这个简单的例子:

  //文件TestController.java 
public interface TestController {

public List< Test>找到所有();



// file TestControllerImp.java
@Controller
public class TestControllerImp implements TestController {

@Autowired
private SessionFactory sessionFactory;

public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}

public List< Test> findAll(){
return sessionFactory.getCurrentSession()。createQuery(from Test)。list();
}

}

// file TestService.java
@Service
public class TestService {

@Autowired
私人TestController控制器;

public boolean flag = true;

public void setController(TestController controller){
this.controller = controller;
}

@Transactional
public List< Test> useController(){
flag = false;
return controller.findAll();
}

}

这是我的尝试:

  TestService s1 = context.getBean(TestService.class); 
TestService s2 = context.getBean(TestService.class);
List< Test>列表= s1.useController();
System.out.println(s1.flag ++ s2.flag);

现在奇怪的行为(即时弹簧非常新):


  1. 如果我声明 @Transactional 方法useController(),则输出为:true true

  2. 如果我将 @Transactional TestService 移动到 TestControllerImp ,并且我用 @Transactional 声明了findAll(),输出为:false false。

为什么我有这种行为?我知道默认 @Autowired 类是单数的,但为什么在第一种情况下这个标记仍然是真的?



解决方案

@Transactional机制在默认情况下在JDK代理上工作,并且仅在接口上工作。 b
$ b

因此,如果让 TestService 作为接口并且 TestServiceImpl 那么上面的代码应该工作。



例如将类声明更改为:

  @Service 
public class TestServiceImpl implements TestService {

但测试代码必须引用接口,而不是类:

  //此代码保持不变
TestService s1 = context.getBean(TestService.class);
TestService s2 = context.getBean(TestService.class);

参考:


  • < tx:advice /> 设置(Spring Reference) //static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotationsrel =nofollow>使用 @Transactional (Spring Reference)

  • TransactionProxyFactorybean (javadoc)

i wrote this simple example:

//file TestController.java
public interface TestController {

    public List<Test> findAll();

}

//file TestControllerImp.java
@Controller
public class TestControllerImp implements TestController{

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory=sessionFactory;
    }

    public List<Test> findAll() {
        return sessionFactory.getCurrentSession().createQuery("from Test").list();
    }

}

//file TestService.java
@Service
public class TestService {

    @Autowired
    private TestController controller;

    public boolean flag=true;

    public void setController(TestController controller){
        this.controller=controller;
    }

    @Transactional
    public List<Test> useController(){
        flag=false;
        return controller.findAll();
    }

}

And this is my try:

TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);
List<Test> list=s1.useController();
System.out.println(s1.flag+"  "+s2.flag);

Now the strange behaviour (im very new with spring):

  1. If i declare @Transactional the method "useController()", the output is: true true
  2. If i move @Transactional from TestService to TestControllerImp, and i declare "findAll()" with @Transactional, the output is: false false.

Why i have this behaviour? I know by default @Autowired classes are singletone, but why in the first case the flag still remains true?

Thanks all.

解决方案

The @Transactional mechanism works on JDK proxies per default and those work on interfaces only.

So if you let TestService be an interface and TestServiceImpl be its implementation, then the above code should work.

e.g. change the class declaration to this:

@Service
public class TestServiceImpl implements TestService {

but the test code must reference the interface, not the class:

// this code remains unchanged
TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);

Reference:

这篇关于春天和@transactional,这是正常的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆