【问题标题】:Spring transactioninterceptor is invoked when no class or method annotated with transactional当没有使用事务注释的类或方法时调用 Spring 事务拦截器
【发布时间】:2016-09-01 13:05:26
【问题描述】:

我正在开发一个在引擎盖下使用弹簧的 gigaspace xap 应用程序。 gigaspaces 提供的 jini 事务管理器不支持序列化。

我有一个使用 spring-batch 处理文件的类。下面是它是如何调用作业的

public class FileProcessor implements BasicFileProcessor {
    @Value("${feeddownload.basedir}")
    private String baseDir;
    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job cmJob;
    @Autowired
    private MapJobRepositoryFactoryBean repositoryFactoryBean;

    @Override
    public void process(RiskRunCompletion riskRunCompletion, VersionedSliceName versionedSliceName, GigaSpace gigaSpace) {
        Transaction tx = gigaSpace.getCurrentTransaction();

        try {
            //Adding current time to the parameter, to enable multiple times calling job with same parameters
            long currentTimeInMillis = System.currentTimeMillis();
            JobParameter currentTimeInMillinsParam = new JobParameter(currentTimeInMillis);

            Map parameterMap = new LinkedHashMap();
            addDirectoryParams(valuationSliceRun, parameterMap);

            parameterMap.put(CURRENT_TIME, currentTimeInMillinsParam);

            JobParameters paramMap = new JobParameters(parameterMap);
            JobExecution cmExecution = launchJobWithParameters(paramMap);
            for (Throwable t : cmExecution.getAllFailureExceptions()) {
                throw new RuntimeException(t);
            }
        } catch (Exception e) {
            throw new RuntimeException("Exception during batch job", e);
        } finally {
            repositoryFactoryBean.clear();
        }

    }

    private JobExecution launchJobWithParameters(JobParameters paramMap) throws Exception {
        return jobLauncher.run(cmJob, paramMap);
    }
}

流程方法是从不同的类调用的,如下所示

public class FileBasedProcessingEventListener implements ApplicationContextAware {
    @Value("${feeddownload.basedir}")
    private String baseDir;

    @Autowired
    private BasicFileProcessor cmProcessor;

    @Autowired
    private FileBasedProcessingExceptionHandler fileBasedProcessingExceptionHandler;


    public void handle(FileBasedProcessingEvent fileBasedProcessingEvent, GigaSpace gigaSpace) throws IOException {
        LOGGER.info("Processing file based processing event : " + fileBasedProcessingEvent);
        createLockFiles(fileBasedProcessingEvent);
        handleEvent(fileBasedProcessingEvent, gigaSpace);
    }

    private void handleEvent(FileBasedProcessingEvent fileBasedProcessingEvent, GigaSpace gigaSpace) {
        Transaction tx = gigaSpace.getCurrentTransaction();

        cmProcessor.process(fileBasedProcessingEvent.getRiskRunCompletion(), versionedSliceName, gigaSpace);


    }

}

Handle 方法是从框架中调用的。现在我不知道为什么我会得到如下异常

Caused by: org.springframework.transaction.InvalidIsolationLevelException: Jini Transaction Manager does not support serializable isolation level
    at org.openspaces.core.transaction.manager.AbstractJiniTransactionManager.applyIsolationLevel(AbstractJiniTransactionManager.java:271)
    at org.openspaces.core.transaction.manager.AbstractJiniTransactionManager.doJiniBegin(AbstractJiniTransactionManager.java:251)
    at org.openspaces.core.transaction.manager.AbstractJiniTransactionManager.doBegin(AbstractJiniTransactionManager.java:207)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:372)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:417)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:255)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)

没有一个类被标记为事务性的,我不确定为什么当我没有将任何类或任何方法标记为事务时调用 TransactionInterceptor,它不应该受到任何关注。我还使用了 Transaction tx = gigaSpace.getCurrentTransaction();检查事务是否未激活,它仅作为 null 出现

当没有一个类被标记为事务时,我很困惑为什么 spring 试图在事务下调用此方法

【问题讨论】:

    标签: spring transactions gigaspaces


    【解决方案1】:

    看起来 Gigaspaces 事务管理器是基于 Spring 事务管理基础架构的,这可以从文档 here 中推断出来 - 因此,如果您使用 Gigaspaces 事务 API,那么您正在使用 Spring 事务管理。同样值得一看的是 xml 配置文件中的任何事务管理器配置,它会指向确切的事务管理器类。

    【讨论】:

    • 同意spring事务管理是gigaspace的核心,但是当没有一个类被标记为事务性时我很困惑为什么spring试图在事务下调用这个方法?
    • 尝试将 org.springframework.transaction 置于调试模式,看看能否获得该信息
    【解决方案2】:

    似乎确实在使用事务,检查是否在 pu.xml 中定义了事务管理器,特别是检查 jobLauncher 初始化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      相关资源
      最近更新 更多