为什么春豆自调用在这里为事务工作



环境 :

雄猫 6

春季 4

冬眠 4

春季MVC

法典:

我有以下服务层类:

public interface AbhisheskService {
    public List<AbhishekDTO> findByMatchingCriteria(AbhishekDetailsSearchDTO searchDto);
}
@Service("abhishekService")
public class AbhishekServiceImpl implements AbhisheskService {

    @Autowired
    private AbhishekDao abhishekDao;    
    @Transactional
    public List<AbhishekDTO> findByMatchingCriteria(AbhishekDetailsSearchDTO searchDto) {
        return getAbs();
    }   

    public List<AbhishekDTO> getAbs(){
        Abhishekdetails absDt = this.abhishekDao.get(4L);
        return null;
    }
}

AbhishekDao是一个标准的DAO层接口,它扩展了GenericDAO超级接口。

public interface AbhishekDao extends GenericDAO<Abhishekdetails, Long>{
    public List<Abhishekdetails> findByMatchingCriteria(AbhishekDetailsSearchDTO searchDto);
}

我的问题是:

findByMatchingCriteria方法标有@Transactional.

此方法调用另一个方法getAbs该方法未标记为@Transactional,并在findByMatchingCriteria(自调用)中调用。

根据我的理解,因为:

1)findByMatchingCriteria在自身内部调用getAbs(自调用),getAbs()方法不应该在事务中运行。由于它在这里绕过了动态创建的代理

2)此外,getAbs没有@Transactional注释。

3)但是当getAbs调用this.abhishekDao.get(4L)一切正常时,会检索到包含ID 4L的记录。DAO Bean 正在调用它内部的sessionFactory.getCurrentSession()以从 DB 获取对象。但是为什么会这样呢?因为不应该有任何活跃的交易。

4)为什么上面的代码有效? 很多关于 Spring 事务管理的帖子都指出自调用是行不通的。(甚至是春季文档)。

那为什么上面的设置有效?

我在这里错过了什么吗?

还是我对春季交易的理解不正确?

请回复,因为我在这里感到困惑

它的工作方式是:- AbhishekServiceImpl bean 被包裹在代理中。

  • findByMatchingCriteria@Transactional,所以在调用该方法之前,Spring 从连接池中获取新的数据库连接,并将自动提交设置为 false。
  • 事务绑定到线程,因此此线程上的其他方法将使用此连接。
  • 执行findByMatchingCriteriagetAbs的方法
  • findByMatchingCriteria之后,Spring 调用在连接上提交(如果发生RuntimeException则回滚)。

所以你的代码在事务中大约findByMatchingCriteria

不会创建事务的情况是,如果您在getAbs上具有@Transactional,但在findByMatchingCriteria上没有(反向调用),并且您在服务外部调用findByMatchingCriteria。但是,如果您只调用服务之外的getAbs,它将在事务中。

更清晰的例子:

@Service
public class MyServiceImpl implements MyService{   
    @Autowired
    private MyDao myDao;    
    @Transactional
    public List<T> transactionalMethod() {
        return this.myDao.get(4L);
    }   
    public List<T> notTransactionalMethod(){
        return transactionalMethod();
    }
}

在其他一些类中:

     @Component
        public class SomeClass {
            @Autowired
            private MyService myService;
            public void someMethod(){
                  myService.transactionalMethod();//will be in transaction. Here actualy you go to the proxy first and then it calls the real method. 
                  myService.notTransactionalMethod();//will not be in transaction and hibernate will throw an error. 
                                                     //You go to the proxy, but doesent do anything special because the method is not transactional and it calls the real method, 
                                                     //but here you dont't got trough the proxy so the @Transactional is ignored.
            }
        }

相关内容

最新更新