如何在非spring管理的bean中启动事务?

时间:2014-03-17 18:22:10

标签: java spring transactions spring-transactions

我有一个Spring 3.2.8应用程序,其中我有一个特殊情况,我希望在Context Listener中启动一个事务。

我知道并且意识到侦听器不是Spring托管bean,所以我不完全确定如何将我的方法标记为@Transactional。我已经尝试将bean标记为@Configurable,但这似乎不起作用;我猜b / c应用程序服务器在加载spring上下文之前实例化这个bean。

我已使用TransactionAspectSupport.currentTransactionStatus()检查了交易状态,但是当没有托管开放交易时,我会收到NoTransactionException抛出。

Spring中是否有任何内容允许我将此方法标记为事务的一部分?

@Configurable
public class PatchEngineContextListener implements ServletContextListener{

    // SLF4J logger
    private static final Logger logger = LoggerFactory.getLogger(PatchEngineContextListener.class);


    // HELPERS
    private ApplicationContext appContext;
    @Autowired private PatchService patchService;
    @Autowired private PatchEngine patchEngine;

    @Override
    @Transactional
    public void contextInitialized(ServletContextEvent sce) {

        // get the app context
        appContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
        appContext.getAutowireCapableBeanFactory().autowireBean(this);

        logger.info( TransactionAspectSupport.currentTransactionStatus().toString() );

        try {
            setPatchEngineUser();
            patchEngine.execute();
            clearPatchEngineUser();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

错误堆栈跟踪:

org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope
    at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:110)
    at com.ia.system.patch.engine.PatchEngineContextListener.contextInitialized(PatchEngineContextListener.java:92)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

Web.xml中:

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Patch Engine launched after spring finishes setting up its context -->
<listener>
    <listener-class>com.ia.system.patch.engine.PatchEngineContextListener</listener-class>
</listener> 

的applicationContext.xml:

<context:spring-configured/>

0 个答案:

没有答案