Configurar sincronización bidireccional entre dos sistemas en Jitterbit Studio
Introducción
La sincronización bidireccional mantiene los registros consistentes entre dos sistemas separados propagando cambios en cualquier dirección: las actualizaciones realizadas en el sistema A se escriben en el sistema B, y las actualizaciones realizadas en el sistema B se escriben de vuelta en el sistema A.
El desafío principal es evitar bucles infinitos. Cuando Studio escribe un registro en el sistema B, la detección de cambios del sistema B ve ese registro como una nueva modificación y (sin una salvaguarda) desencadena la sincronización de B a A, que escribe el registro de vuelta en el sistema A, lo que luego desencadena la sincronización de A a B nuevamente. Un campo de bandera de sincronización en los registros de cada sistema es la forma más confiable de romper este ciclo: cada dirección de sincronización marca los registros que escribe como "sincronizados por Jitterbit", y la dirección opuesta filtra esos registros de sus consultas.
Esta guía utiliza Salesforce y NetSuite como los dos sistemas de ejemplo y asume familiaridad con la configuración de conexiones, transformaciones y scripts de Studio. Para obtener información sobre temas relacionados, consulta:
- Consultar registros de Salesforce usando SOQL
- Programar una operación para ejecutarse automáticamente
Patrón de diseño
El patrón utiliza dos cadenas de operaciones independientes:
Dos campos booleanos personalizados llevan el estado de sincronización, uno en cada sistema externo:
- Salesforce:
Jitterbit_Synced__c:falsecuando un usuario modificó por última vez el registro;truecuando Studio escribió por última vez el registro. - NetSuite:
custbody_jb_synced: la misma semántica.
Cada sistema también requiere una regla de automatización que restablezca el campo a false cada vez que un usuario modifique un registro. Esto garantiza que los cambios iniciados por el usuario siempre se recojan en la siguiente ejecución de sincronización, mientras que los registros escritos por Studio se ignoren.
Cómo se previene el bucle:
- Un usuario modifica una cuenta en Salesforce. La regla de automatización establece
Jitterbit_Synced__c = false. - La cadena de Salesforce a NetSuite consulta registros donde
Jitterbit_Synced__c = falsey encuentra el registro modificado. - Studio escribe el registro en NetSuite con
custbody_jb_synced = true, luego estableceJitterbit_Synced__c = truede vuelta en Salesforce. - La cadena de NetSuite a Salesforce consulta NetSuite para registros donde
custbody_jb_synced = false. El registro del paso 3 se excluye, por lo que no se escribe de vuelta en Salesforce.
Requisitos previos
Antes de configurar las operaciones de Studio, completa los siguientes pasos en cada sistema externo.
En Salesforce
-
En el objeto
Account(u otro objeto que estés sincronizando), crea un campo de casilla de verificación personalizado con la etiqueta Jitterbit Synced y el nombre de APIJitterbit_Synced__c. Establece el valor predeterminado como Unchecked. -
Crea una regla de flujo de trabajo o un flujo de Process Builder que se active en la creación o actualización de registros por un usuario y establezca
Jitterbit_Synced__cenfalse. Esto garantiza que los cambios iniciados por el usuario sean visibles para la cadena de Salesforce a NetSuite.
En NetSuite
-
En el tipo de registro
Customer(u otro tipo de registro que estés sincronizando), crea un campo de casilla de verificación personalizado con la etiqueta Jitterbit Synced e IDcustbody_jb_synced. Establece el valor predeterminado como unchecked. -
Crea un SuiteScript de evento de usuario (
afterSubmit) que se active al guardar el registro y establezcacustbody_jb_synced = false. Utilizacontext.typepara omitir la ejecución cuando el script guarda el registro (como una escritura de sincronización de Jitterbit), de modo que solo los guardados por usuario restablezcan la bandera.
En tu proyecto de Jitterbit
Crea dos variables de proyecto para rastrear la última hora de sincronización exitosa para cada dirección:
sf_last_sync_time: la última vez que la cadena de Salesforce a NetSuite se ejecutó correctamente. Establece un valor inicial de una fecha en el pasado, por ejemplo2020-01-01T00:00:00Z.ns_last_sync_time: la última vez que la cadena de NetSuite a Salesforce se ejecutó correctamente. Establece el mismo valor inicial.
Parte 1: Configurar la cadena de operaciones de Salesforce a NetSuite
Paso 1: Configurar la actividad Salesforce Query
-
En el lienzo de diseño, arrastra una actividad Salesforce Query desde un endpoint Salesforce existente al lienzo para iniciar la cadena.
-
Haz doble clic en la actividad para abrir su configuración.
-
Nombre: Ingresa
Query Salesforce Accounts. -
Objeto: Selecciona Account.
-
Condiciones de consulta: Agrega dos condiciones:
Jitterbit_Synced__ces igual afalseLastModifiedDatemayor que$sf_last_sync_time
En conjunto, estas condiciones devuelven solo los registros modificados por usuarios desde la última ejecución de sincronización.
-
Selecciona los campos a devolver:
Id,Namey cualquier otro campo que se asigne a NetSuite. -
Haz clic en Finalizado.
Paso 2: Configurar la transformación
-
Agrega un paso de Transformación después de la actividad Salesforce Query.
-
Establece el esquema de origen en la respuesta de Salesforce Query y el esquema de destino en la estructura de registro de NetSuite
Customer. -
Asigna los campos de origen de Salesforce a los campos de destino correspondientes en NetSuite.
-
Agrega un script a nivel raíz (fuera del nodo de bucle) que marque cada registro escrito como "sincronizado por Jitterbit" y capture el tiempo de ejecución actual:
target.custbody_jb_synced = true; $sync_run_time = Now();Establecer
custbody_jb_synced = trueen cada registro de NetSuite escrito por esta cadena es lo que impide que la cadena NetSuite-a-Salesforce los detecte y los escriba nuevamente. -
En el mismo script a nivel raíz, agrega el ID de cada registro de origen a una variable global para que el script posterior a la sincronización pueda actualizar Salesforce:
$synced_sf_ids = $synced_sf_ids + If(Length($synced_sf_ids) > 0, ",", "") + Source.Id;
Paso 3: Configurar la actividad NetSuite Upsert
-
Agrega una actividad NetSuite Upsert después de la transformación.
-
Nombre: Ingresa
Upsert NetSuite Customers. -
Tipo de registro: Selecciona Customer.
-
Campo de ID externo: Selecciona el campo que almacena el ID de registro de Salesforce en NetSuite (por ejemplo,
custentity_sf_id). Este campo es la clave de upsert: si existe un registro coincidente, se actualiza; de lo contrario, se crea un nuevo registro. -
Haz clic en Finalizado.
Paso 4: Escribir el script posterior a la sincronización
Después de hacer un upsert a NetSuite, actualiza Salesforce para marcar los mismos registros como procesados. Esto evita que se vuelvan a consultar en la siguiente ejecución.
-
Agrega un paso de Script después de la actividad NetSuite Upsert.
-
Ingresa lo siguiente:
// Mark the synced Salesforce records so the next run skips them. // $synced_sf_ids is a comma-separated list of Salesforce IDs built in the transformation. RunOperation("<TAG>operation:Mark Salesforce Records Synced</TAG>"); // Advance the last-sync timestamp so the next query picks up only newer changes. $sf_last_sync_time = $sync_run_time; SetVar("sf_last_sync_time", $sf_last_sync_time); // Reset for the next run. $synced_sf_ids = ""; -
Crea una operación separada llamada
Mark Salesforce Records Syncedque contenga una actividad Salesforce Update. Configura la actividad para establecerJitterbit_Synced__c = trueen cada ID de registro ensynced_sf_ids. Utiliza una transformación que dividasynced_sf_idsen comas y asigne cada ID a una carga útil de actualización. -
También inicializa
$synced_sf_ids = ""al principio de cualquier script de controlador que llame a esta cadena, para que la lista de IDs esté vacía al inicio de cada ejecución.
Parte 2: Configurar la cadena de operaciones NetSuite-a-Salesforce
La cadena NetSuite-a-Salesforce sigue la misma estructura que la Parte 1 con los sistemas de origen y destino intercambiados.
Paso 1: Configurar la actividad NetSuite Search
-
Arrastra una actividad NetSuite Search al lienzo.
-
Nombre: Ingresa
Search NetSuite Customers. -
Filtro de búsqueda: Agrega dos condiciones:
custbody_jb_syncedesfalselastmodifieddatedespués de$ns_last_sync_time
-
Campos a devolver: Selecciona
internalId,entityId,custentity_sf_idy cualquier otro campo que se asigne a Salesforce. -
Haz clic en Finalizado.
Paso 2: Configurar la transformación
-
Agrega un paso de Transformación después de la actividad NetSuite Search.
-
Establece el esquema de origen en la respuesta de NetSuite Search y el esquema de destino en la estructura Salesforce
Account. -
Asigna los campos de origen de NetSuite a los campos de destino correspondientes en Salesforce.
-
Añade un script a nivel raíz que marque cada registro de Salesforce como "sincronizado por Jitterbit" y recopile las IDs de NetSuite para la actualización posterior a la sincronización:
target.Jitterbit_Synced__c = true; $sync_run_time = Now(); $synced_ns_ids = $synced_ns_ids + If(Length($synced_ns_ids) > 0, ",", "") + Source.internalId;
Paso 3: Configura la actividad de Upsert de Salesforce
-
Añade una actividad Upsert de Salesforce después de la transformación.
-
Nombre: Ingresa
Upsert Salesforce Accounts. -
Campo de ID externo: Selecciona el campo que almacena la ID interna de NetSuite en Salesforce (por ejemplo,
NetSuite_ID__c). -
Haz clic en Finished.
Paso 4: Escribe el script posterior a la sincronización
-
Añade un paso Script después de la actividad Upsert de Salesforce.
-
Ingresa lo siguiente:
RunOperation("<TAG>operation:Mark NetSuite Records Synced</TAG>"); $ns_last_sync_time = $sync_run_time; SetVar("ns_last_sync_time", $ns_last_sync_time); $synced_ns_ids = ""; -
Crea una operación separada llamada
Mark NetSuite Records Syncedque contenga una actividad Update de NetSuite que establezcacustbody_jb_synced = trueen cada ID de registro ensynced_ns_ids.
Parte 3: Programa las operaciones
Ambas cadenas se ejecutan en programas de operación. Para reducir la posibilidad de que ambas cadenas se ejecuten simultáneamente y recojan escrituras en curso una de la otra, desfasa sus horas de inicio.
-
Asigna un programa a la cadena de Salesforce a NetSuite. Para un intervalo de sincronización de 15 minutos, configúralo para que se ejecute a los 0, 15, 30 y 45 minutos de cada hora.
-
Asigna un programa a la cadena de NetSuite a Salesforce y desfásalo por la mitad del intervalo (por ejemplo, 7, 22, 37 y 52 minutos de cada hora).
Para obtener instrucciones paso a paso sobre cómo crear y asignar programas, consulta Programa una operación para que se ejecute automáticamente.
Nota
Desfasar reduce la superposición pero no la elimina. Si una ejecución de sincronización toma más tiempo que el intervalo de desfase, ambas cadenas pueden ejecutarse simultáneamente. Para sincronizaciones de alto volumen, considera añadir un bloqueo: al inicio de cada cadena, lee una variable de proyecto o una entrada de Cloud Datastore llamada sync_lock. Si el bloqueo está establecido, sal temprano usando RaiseError. De lo contrario, establece el bloqueo antes de proceder y límpialo en el script posterior a la sincronización.
Verifica la integración
-
Implementa y ejecuta la cadena de Salesforce a NetSuite manualmente.
-
En los registros de operación, confirma que los registros se recuperaron de Salesforce y se escribieron en NetSuite.
-
En NetSuite, abre uno de los registros de cliente sincronizados y confirma que
custbody_jb_syncedesté marcado. -
En Salesforce, abre la cuenta correspondiente y confirma que
Jitterbit_Synced__cesté marcado. -
Ejecuta la cadena de NetSuite a Salesforce. En los registros, confirma que los registros de cliente escritos en el paso 2 no aparezcan en los resultados de búsqueda de NetSuite. Esto confirma que el filtro de prevención de bucles está funcionando: los registros con
custbody_jb_synced = truese excluyen. -
En NetSuite, modifica directamente uno de los registros de cliente sincronizados. El SuiteScript
afterSubmitrestablececustbody_jb_synced = false. Ejecuta la cadena de NetSuite a Salesforce y confirma que el cambio se propague a Salesforce. -
En Salesforce, confirma que la cuenta actualizada tenga
Jitterbit_Synced__c = truedespués de la sincronización. Ejecuta la cadena de Salesforce a NetSuite y confirma que el registro no aparezca en los resultados de la consulta, ya que Jitterbit lo escribió por última vez.
Para un enfoque alternativo para detectar registros cambiados sin campos de marca de sincronización, consulta Detecta y desduplica registros usando funciones hash.