IDEMPIERE-4319 Cascade workflow activities (completing chained documents) exception problem (#122)

Implemented a better approach: save the first workflow savepoint and rollback to that one in case of cascade activities
This commit is contained in:
Carlos Ruiz 2020-06-17 15:44:06 +02:00 committed by GitHub
parent 36d6644879
commit 2a3224ea46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 6 deletions

View File

@ -513,7 +513,17 @@ public class Trx
return null;
}
}
private Savepoint m_lastWFSavepoint = null;
public synchronized void setLastWFSavepoint(Savepoint savepoint) {
m_lastWFSavepoint = savepoint;
}
public synchronized Savepoint getLastWFSavepoint() {
return m_lastWFSavepoint;
}
/**
* Release Savepoint
* @param savepoint

View File

@ -286,7 +286,13 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
if (log.isLoggable(Level.FINE)) log.fine(oldState + "->"+ WFState + ", Msg=" + getTextMsg());
super.setWFState (WFState);
m_state = new StateEngine (getWFState());
saveEx(); // closed in MWFProcess.checkActivities()
boolean valid = save();
if (! valid) {
// the activity could not be updated, probably it was deleted by the rollback to savepoint
// so, set the ID to zero and save it again (insert)
setAD_WF_Activity_ID(0);
saveEx();
}
updateEventAudit();
// Inform Process
@ -336,7 +342,13 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
}
else
m_audit.setEventType(MWFEventAudit.EVENTTYPE_StateChanged);
m_audit.saveEx();
boolean valid = m_audit.save();
if (! valid) {
// the event audit could not be updated, probably it was deleted by the rollback to savepoint
// so, set the ID to zero and save it again (insert)
m_audit.setAD_WF_EventAudit_ID(0);
m_audit.saveEx();
}
} // updateEventAudit
/**
@ -871,8 +883,15 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
//
try
{
if (!localTrx)
savepoint = trx.setSavepoint(null);
if (!localTrx) {
// when cascade workflows, avoid setting a savepoint for each workflow
// use the same first savepoint from the transaction
savepoint = trx.getLastWFSavepoint();
if (savepoint == null) {
savepoint = trx.setSavepoint(null);
trx.setLastWFSavepoint(savepoint);
}
}
if (!m_state.isValidAction(StateEngine.ACTION_Start))
{
@ -925,6 +944,7 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
try
{
trx.rollback(savepoint);
trx.setLastWFSavepoint(null);
} catch (SQLException e1) {}
}
@ -973,7 +993,6 @@ public class MWFActivity extends X_AD_WF_Activity implements Runnable
if (contextLost)
Env.getCtx().remove("#AD_Client_ID");
}
throw new AdempiereException(e);
}
finally
{