spring 和@transactional,这正常吗?
我写了这个简单的例子:
//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();
}
}
这是我的尝试:
TestService s1=context.getBean(TestService.class);
TestService s2=context.getBean(TestService.class);
List<Test> list=s1.useController();
System.out.println(s1.flag+" "+s2.flag);
现在奇怪的行为(我对 spring 非常陌生):
- 如果我声明 @Transactional 方法“useController()”,输出是: true true
- 如果我将
@Transactional
从TestService
移动到TestControllerImp
,并且我用@Transactional
声明“findAll()”,输出是:假假。
为什么我有这种行为?我知道默认情况下 @Autowired
类是单例的,但为什么在第一种情况下该标志仍然保持为 true?
谢谢大家。
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):
- If i declare
@Transactional
the method "useController()", the output is: true true - If i move
@Transactional
fromTestService
toTestControllerImp
, 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
@Transactional 机制默认适用于 JDK 代理,并且仅适用于接口。
因此,如果您让
TestService
是一个接口,而TestServiceImpl
是它的实现,那么上面的代码应该可以工作。例如将类声明更改为:
但测试代码必须引用接口,而不是类:
参考:
设置(Spring 参考)@Transactional< /code>
(Spring 参考)
The @Transactional mechanism works on JDK proxies per default and those work on interfaces only.
So if you let
TestService
be an interface andTestServiceImpl
be its implementation, then the above code should work.e.g. change the class declaration to this:
but the test code must reference the interface, not the class:
Reference:
<tx:advice/>
settings (Spring Reference)@Transactional
(Spring Reference)