spring @Transactional注释

我有一个抽象类和两个扩展它的子类。 我在spring配置文件中有以下内容

    

在我的抽象类中,我有以下方法

 public void importDataToDB(){ //all the good stuff goes in here } @Transactional public void executeInsertUpdateQuery(){ //all the good stuff goes in here } 

我的java代码

 ImportConfigFiles importConfigFiles = (ImportConfigFiles)context.getBean("importConfigFile"); importConfigFiles.setFileLocation(destPath); importConfigFiles.importDataToDB(); 

这不起作用。 executeInsertUpdateQuery()只执行一个本机sql查询。 如果我把@Transactional放在imortDataToDB()上它可以工作,但它会使我的事务变得很大,因为在该方法中我循环遍历文件中的所有行并在db中插入记录。

这是Spring中的主要缺陷之一 – 如果您在同一个类中使用非事务方法调用@Transactional -method,则会忽略@Transactional (除非您使用AspectJ编织)。 这本身不是Spring问题 – EJB具有相同的缺点。

不幸的是,对于基于接口和基于类的代理,您所能做的就是将您的类拆分为两个:

 public class BeanA() { @Resource private BeanB b; public void importDataToDB(){ b.executeInsertUpdateQuery(); } } public class BeanB { @Transactional public void executeInsertUpdateQuery(){ //all the good stuff goes in here } } 

整个喧嚣是由Spring中AOP代理的内部实现引起的。 使用上面的代码,每次从非事务BeanA调用b.executeInsertUpdateQuery() ,都会启动新事务。

我在博客上写了一篇关于它的故事:陷阱:代理 , Spring AOP谜语和Spring AOP之谜揭秘 。

不太确定,问题是什么,但@Transactional将整个方法包装在一个事务中,所以如果你在一个方法中导入所有东西,它显然会很大。 优点是,如果在某个地方导入失败,整个事务将无法执行,数据库中也不会出现错误数据。

如果您不想这样做,您将必须自己管理事务或为您的数据子集调用@Transactional注释方法,就像您现在正在进行一次导入,但也许您为10个文件执行此操作或其他例如逻辑限制。