Asynchronous Operation Replay

Upload operation replay records asynchronously.

Note: This topic is not applicable for DOE-based applications.

When an application calls submitPendingSubmitPending on an MBO on which a create, update, or delete operation is performed, an operation replay record is created on the device local database.

When synchronizeSynchronize is called, the operation replay records are uploaded to the server. The method returns without waiting for the backend to replay those records. The synchronizeSynchronize method downloads all the latest data changes and the results of the previously uploaded operation replay records that the backend has finished replaying in the background. If you choose to disable asynchronous operation replay, each synchronizeSynchronize call will wait for the backend to finish replaying all the current uploaded operation replay records.

For DOE-based applications, the operation replay record is sent to Unwired Server through the message channel when submitPending is called. When operation replay is done on server, one of the callback methods onReplaySuccess and onReplayFailure will be invoked depends on the result of the replay.

When Sybase Unwired Platform does an update operation replay, if the primary key or foreign key of the MBO is generated by the EIS and the MBO's content coming from the device has no primary key or foreign key, the Unwired Server loads the primary key or foreign key from the CDB to merge the incoming values with the CDB content so that a full row (graph) can be communicated to the EIS.

oneMBO mbo = new oneMBO();
mbo.setXX(xx);
....
mbo.create();
mbo.submitPending();
mbo.setXX(yy);
....
mbo.update();
mbo.submitPending();
DBClass.synchronize()
oneMBO mbo = new oneMBO();
mbo.SetXX(xx);
....
mbo.Create();
mbo.SubmitPending();
mbo.SetXX(yy);
....
mbo.Update();
mbo.SubmitPending();
DBClass.Synchronize()
This feature is enabled by default. You can enable or disable the feature by setting the asyncReplay property in the synchronization profile. The following code shows how to disable asynchronous replay:
SMP101DB.getSynchronizationProfile().setAsyncReplay(false);
[[SMP101SMP101DB getSynchronizationProfile] setAsyncReplay:NO]; 
SMP101DB.GetSynchronizationProfile().AsyncReplay = false;

When the application is connected (by Application.startConnection()Application.StartConnection() or Application.registerApplicationApplication.RegisterApplication), it may receive background notifications and trigger a synchronize or other database operation. If you try to delete the database, you may receive database exceptions.

Before deleting the database, stop the application connection (Application.stopConnection()Application.StopConnection()).

You can specify an upload-only synchronization where the client sends its changes to the server, but does not download other changes from the server. This type of synchronization conserves device resources when receiving changes from the server.
public static void beginSynchronize(com.sybase.collections.GenericList<com.sybase.persistence.SynchronizationGroup> sgs,Object context, boolean uploadOnly)
public static void beginSynchronize(com.sybase.collections.ObjectList sgs,Object context, boolean uploadOnly)
+ (void)beginSynchronize:(SUPObjectList*)synchronizationGroups withContext:(NSString*)context withUploadOnly:(BOOL) uploadOnly
public static void BeginSynchronize(Sybase.Collections.GenericList<Sybase.Persistence.ISynchronizationGroup> sgs,object context, bool uploadOnly)
When asynchronous replay is enabled and the replay is finished, the onSynchronizeOnSynchronize callback method is invoked with a SynchronizationStatus value of SynchronizationStatus.ASYNC_REPLAY_COMPLETED. Use this callback method to invoke a synchronize call to pull in the results, as shown in the following callback handler.
public class MyCallbackHandler extends DefaultCallbackHandler
{
  public int onSynchronize(GenericList<SynchronizationGroup> groups, SynchronizationContext context)
  {
    switch(context.getStatus())
    {
      case SynchronizationStatus.ASYNC_REPLAY_UPLOADED:
        LogMessage("AsyncReplay uploaded");
        break;
      case SynchronizationStatus.ASYNC_REPLAY_COMPLETED:
        // operation replay finished, return SynchronizationAction.CONTINUE
        // will start a background synchronization to pull in the results.
        LogMessage("AsyncReplay Done");
        break;
      default:
        break;
    }

    return SynchronizationAction.CONTINUE;
  } 
}
public class MyCallbackHandler extends DefaultCallbackHandler
{
  public int onSynchronize(ObjectList groups, SynchronizationContext context)
  {
    switch(context.getStatus())
    {
      case SynchronizationStatus.ASYNC_REPLAY_UPLOADED:
        LogMessage("AsyncReplay uploaded");
        break;
      case SynchronizationStatus.ASYNC_REPLAY_COMPLETED:
        // operation replay finished, return SynchronizationAction.CONTINUE
        // will start a background synchronization to pull in the results.
        LogMessage("AsyncReplay Done");
        break;
      default:
        break;
    }

    return SynchronizationAction.CONTINUE;
  } 
}
public class MyCallbackHandler extends DefaultCallbackHandler
{
  public int onSynchronize(ObjectList groups, SynchronizationContext context)
  {
    switch(context.getStatus())
    {
      case SynchronizationStatus.ASYNC_REPLAY_UPLOADED:
        LogMessage("AsyncReplay uploaded");
        break;
      case SynchronizationStatus.ASYNC_REPLAY_COMPLETED:
        [SUP101SUP101DB  synchronize:@"default"];
        LogMessage("AsyncReplay Done");
        break;
      default:
        break;
    }

    return SynchronizationAction.CONTINUE;
  } 
}
public virtual SynchronizationAction OnSynchronize( 
  Sybase.Collections.GenericList<ISynchronizationGroup> groups,
  SynchronizationContext context)
{
  switch(context.Status)
  {
    case SynchronizationStatus.ASYNC_REPLAY_UPLOADED:
      LogMessage("AsyncReplay uploaded");
      break;
    case SynchronizationStatus.ASYNC_REPLAY_COMPLETED:
      // operation replay finished
      if (busy)
      {
        // if busy, don't do synchronize now
        return SynchronizationAction.CANCEL;
      }
      break;
    default:
      break;
  }
            return SynchronizationAction.CONTINUE;
}