我想在.xls中导出一些数据库结果,我想在另一个Thread中执行。当我创建Thread时它执行得很好,但是当我试图获取空间的childNode时它返回null但是如果我不使用该线程,程序就会很好。
这是调用线程并执行导出的类的代码:
public class ExportarResultadosExcellActionBean {
...
public void iniciaHilo(final ActionEvent event){
HiloExportaExcell hilo = new HiloExportaExcell(event, this.nodeService);
Thread t = new Thread(hilo);
t.start();
}
...
private List<NodeRef> recuperarUnidadesDidacticas(final NodeRef campaniaNodeRef) throws Exception {
List<NodeRef> unidadesOrdenadasList = new ArrayList<NodeRef>();
try {
// Recuperar las Unidad Didáctica de la Unidad Didáctica de la Campaña
Set<QName> childNodeUnidadQNames = new HashSet<QName>();
childNodeUnidadQNames.add(ContentModelEvaluacion.TYPE_UN_DIDACTICA);
**List<ChildAssociationRef> unidadesList =
this.nodeService.getChildAssocs(campaniaNodeRef, childNodeUnidadQNames);**
...
这是HiloExportaExcell.class的代码
public class HiloExportaExcell extends Thread {
private ActionEvent evento;
private transient NodeService node;
public HiloExportaExcell(ActionEvent event, NodeService nodeservice){
this.evento = event;
this.setNode(nodeservice);
}
public void run(){
ExportarResultadosExcellActionBean exportaExcell = new ExportarResultadosExcellActionBean();
exportaExcell.setNodeService(this.getNode());
exportaExcell.exportar(evento);
}
public NodeService getNode() {
return node;
}
public void setNode(NodeService node) {
this.node = node;
}
}
答案 0 :(得分:2)
如果您需要在另一个线程中工作,您(很可能)需要确保正确设置安全性和事务性上下文。你可以自己做:
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
@Override
public Object doWork() throws Exception {
getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Object>() {
@Override
public Object execute() throws Throwable {
// do stuff here
return null;
}
});
return null;
}
}, AuthenticationUtil.getFullyAuthenticatedUser());
或者通过使用适当的参数调用ActionService.executeAction
来创建一个动作并异步执行它。
答案 1 :(得分:1)
这种行为很可能来自事务隔离。当您执行以下步骤时:
然后第二个线程将无法看到新节点。这不是错误,而是事务语义的结果......以及Spring对事务上下文的实现。
如果你在第一次提交中的事务之后开始第二次,那么一切都应该按预期工作。