春天和@transactional,这是正常的? [英] spring and @transactional, is this normal?
问题描述
//文件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);
现在奇怪的行为(即时弹簧非常新):
- 如果我声明
@Transactional
方法useController(),则输出为:true true - 如果我将
@Transactional
从TestService
移动到TestControllerImp
,并且我用@Transactional
声明了findAll(),输出为:false false。
为什么我有这种行为?我知道默认 @Autowired
类是单数的,但为什么在第一种情况下这个标记仍然是真的?
@Transactional机制在默认情况下在JDK代理上工作,并且仅在接口上工作。 b
$ b
因此,如果让 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)
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.
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:
<tx:advice/>
settings (Spring Reference)- Using
@Transactional
(Spring Reference) - TransactionProxyFactorybean (javadoc)
这篇关于春天和@transactional,这是正常的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!