我有一个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/>