Grosso modo, mi solución tiene que ver con un sistema de puntos de restauración (
save points) universales encadenables, implementados en clases derivadas de TSQLConnection y TClientDataSet. Cuando uno de estos conjuntos de datos cliente hace ApplyUpdates,
mira si hay un
punto padre "marcado" (transacción iniciada en el servidor), en cuyo caso, efectivamente, conserva el
ChangeLog tras la operación. Pero debe realizarse el
ApplyUpdates por cada conjunto de datos, como estamos acostumbrados. Cuando ese punto padre se confirma (
Commit de transacción), todos esos conjuntos de datos "
hijos" de la transacción y pendientes de confirmar hacen su
MergeChangeLog .
Pero para no ir tan lejos, te comento que
la clave para conservar el ChangeLog después de un ApplyUpdates es evitar que se ejecute el método TCustomClientDataSet.MergeChangeLog cuando realizas esa operación.
En el código fuente de DBClient.pas podrás observar que ApplyUpdates llama al método Reconcile, y éste a MergeChangeLog cuando el envío al servidor no tuvo errores. Como Reconcile y MergeChangeLog no son métodos virtuales, no pueden ser redefinidos (
Override) en una clase derivada. Entonces, si se quiere evitar que un ApplyUpdates termine llamando a MergeChangeLog, toca redefinir el propio método ApplyUpdates, el cual sí es virtual.
Puedes reescribir el código de dicho método en una clase derivada "
TMiClientDataSet", evitando que se llame a Reconcile cuando DoApplyUpdates (otro método involucrado ahí) no regrese errores. De esa manera consigues que el registro de cambios (
ChangeLog) permanezca intacto aún después de aplicar todas las actualizaciones al servidor.
Más adelante, cuando hagas el
Commit o el
Rollback de la transacción, podrás llamar directamente a MergeChangeLog o a CancelUpdates, respectivamente. De esta forma logras envolver a cualquier grupo de objetos TClientDataSet en una transacción.
Espero te sea de utilidad. Síguenos contando sobre tus progresos en el caso.
Un abrazo virtual.
Al González.