Ir para o conteúdo

Configurar sincronização bidirecional entre dois sistemas no Jitterbit Studio

Introdução

A sincronização bidirecional mantém os registros consistentes em dois sistemas separados propagando mudanças em qualquer direção: as atualizações realizadas no sistema A são gravadas no sistema B, e as atualizações realizadas no sistema B são gravadas de volta no sistema A.

O desafio principal é evitar loops infinitos. Quando o Studio grava um registro no sistema B, a detecção de mudanças do sistema B vê esse registro como uma nova modificação e (sem uma proteção) dispara a sincronização B-para-A, que grava o registro de volta no sistema A, o que então dispara a sincronização A-para-B novamente. Um campo de sinalizador de sincronização nos registros de cada sistema é a forma mais confiável de interromper esse ciclo: cada direção de sincronização marca os registros que grava como "sincronizados pelo Jitterbit" e a direção oposta filtra esses registros de suas consultas.

Este guia usa Salesforce e NetSuite como os dois sistemas de exemplo e presume familiaridade com a configuração de conexões, transformações e scripts do Studio. Para mais informações sobre tópicos relacionados, consulte:

Padrão de design

O padrão usa duas cadeias de operações independentes:

%%{init: {"themeVariables": {"lineColor": "#6b7280", "edgeLabelBackground": "#f5f5f5"}}}%% flowchart LR A[Salesforce Query] --> B[Transformation] --> C[NetSuite Upsert] --> D[Script] E[NetSuite Search] --> F[Transformation] --> G[Salesforce Upsert] --> H[Script]

Dois campos booleanos personalizados carregam o estado de sincronização, um em cada sistema externo:

  • Salesforce: Jitterbit_Synced__c: false quando um usuário modificou o registro pela última vez; true quando o Studio gravou o registro pela última vez.
  • NetSuite: custbody_jb_synced: a mesma semântica.

Cada sistema também requer uma regra de automação que redefine o campo para false sempre que um usuário modifica um registro. Isso garante que as mudanças iniciadas pelo usuário sejam sempre capturadas pela próxima execução de sincronização, enquanto os registros gravados pelo Studio são ignorados.

Como o loop é evitado:

  1. Um usuário modifica uma conta no Salesforce. A regra de automação define Jitterbit_Synced__c = false.
  2. A cadeia Salesforce-para-NetSuite consulta registros onde Jitterbit_Synced__c = false e encontra o registro modificado.
  3. O Studio grava o registro no NetSuite com custbody_jb_synced = true e depois define Jitterbit_Synced__c = true de volta no Salesforce.
  4. A cadeia NetSuite-para-Salesforce consulta o NetSuite por registros onde custbody_jb_synced = false. O registro da etapa 3 é excluído, portanto não é gravado de volta no Salesforce.

Pré-requisitos

Antes de configurar as operações do Studio, conclua as etapas a seguir em cada sistema externo.

No Salesforce

  1. No objeto Account (ou qualquer objeto que você esteja sincronizando), crie um campo de caixa de seleção personalizado com o rótulo Jitterbit Synced e o nome da API Jitterbit_Synced__c. Defina o valor padrão como Desmarcado.

  2. Crie uma regra de fluxo de trabalho ou um fluxo do Process Builder que dispare na criação ou atualização de registro por um usuário e defina Jitterbit_Synced__c como false. Isso garante que as mudanças iniciadas pelo usuário sejam visíveis para a cadeia Salesforce-para-NetSuite.

No NetSuite

  1. No tipo de registro Customer (ou qualquer tipo de registro que você esteja sincronizando), crie um campo de caixa de seleção personalizado com o rótulo Jitterbit Synced e ID custbody_jb_synced. Defina o valor padrão como desmarcado.

  2. Crie um SuiteScript de evento de usuário (afterSubmit) que dispare ao salvar o registro e defina custbody_jb_synced = false. Use context.type para ignorar a execução quando o registro é salvo por um script (como uma gravação de sincronização do Jitterbit), para que apenas salvamentos de usuários redefinam o sinalizador.

No seu projeto Jitterbit

Crie duas variáveis de projeto para rastrear o último horário de sincronização bem-sucedida para cada direção:

  • sf_last_sync_time: a última vez que a cadeia Salesforce-para-NetSuite foi executada com sucesso. Defina um valor inicial de uma data no passado, por exemplo 2020-01-01T00:00:00Z.
  • ns_last_sync_time: a última vez que a cadeia NetSuite-para-Salesforce foi executada com sucesso. Defina o mesmo valor inicial.

Parte 1: Configurar a cadeia de operações Salesforce-para-NetSuite

Etapa 1: Configurar a atividade Query do Salesforce

  1. Na tela de design, arraste uma atividade Query do Salesforce de um endpoint Salesforce existente para a tela e inicie a sequência.

  2. Clique duas vezes na atividade para abrir sua configuração.

  3. Nome: Digite Query Salesforce Accounts.

  4. Objeto: Selecione Account.

  5. Condições de consulta: Adicione duas condições:

    • Jitterbit_Synced__c é igual a false
    • LastModifiedDate maior que $sf_last_sync_time

    Juntas, essas condições retornam apenas registros modificados pelos usuários desde a última execução de sincronização.

  6. Selecione os campos a retornar: Id, Name e quaisquer outros campos que mapeiem para o NetSuite.

  7. Clique em Finished.

Etapa 2: Configurar a transformação

  1. Adicione uma etapa de Transformation após a atividade Query do Salesforce.

  2. Defina o esquema de origem como a resposta da Query do Salesforce e o esquema de destino como a estrutura do registro Customer do NetSuite.

  3. Mapeie os campos de origem do Salesforce para os campos de destino correspondentes do NetSuite.

  4. Adicione um script no nível raiz (fora do nó de loop) que marca cada registro gravado como "sincronizado pelo Jitterbit" e captura o tempo da execução atual:

    target.custbody_jb_synced = true;
    $sync_run_time = Now();
    

    Definir custbody_jb_synced = true em cada registro do NetSuite gravado por essa sequência é o que impede que a sequência NetSuite-para-Salesforce os selecione e os grave novamente.

  5. No mesmo script de nível raiz, acrescente o ID de cada registro de origem a uma variável global para que o script pós-sincronização possa atualizar o Salesforce:

    $synced_sf_ids = $synced_sf_ids + If(Length($synced_sf_ids) > 0, ",", "") + Source.Id;
    

Etapa 3: Configurar a atividade Upsert do NetSuite

  1. Adicione uma atividade Upsert do NetSuite após a transformação.

  2. Nome: Digite Upsert NetSuite Customers.

  3. Tipo de registro: Selecione Customer.

  4. Campo de ID externo: Selecione o campo que armazena o ID do registro do Salesforce no NetSuite (por exemplo, custentity_sf_id). Este campo é a chave de upsert: se um registro correspondente existir, ele será atualizado; caso contrário, um novo registro será criado.

  5. Clique em Finished.

Etapa 4: Escrever o script pós-sincronização

Após fazer o upsert para o NetSuite, atualize o Salesforce para marcar os mesmos registros como processados. Isso evita que eles sejam consultados novamente na próxima execução.

  1. Adicione uma etapa de Script após a atividade Upsert do NetSuite.

  2. Digite o seguinte:

    // 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 = "";
    
  3. Crie uma operação separada nomeada Mark Salesforce Records Synced contendo uma atividade Update do Salesforce. Configure a atividade para definir Jitterbit_Synced__c = true em cada ID de registro em synced_sf_ids. Use uma transformação que divide synced_sf_ids em vírgulas e mapeia cada ID para um payload de atualização.

  4. Também inicialize $synced_sf_ids = "" no início de qualquer script do controlador que chame essa sequência, para que a lista de IDs esteja vazia no início de cada execução.

Parte 2: Configurar a sequência de operação NetSuite-para-Salesforce

A sequência NetSuite-para-Salesforce segue a mesma estrutura da Parte 1 com os sistemas de origem e destino invertidos.

Etapa 1: Configurar a atividade Search do NetSuite

  1. Arraste uma atividade Search do NetSuite para a tela.

  2. Nome: Digite Search NetSuite Customers.

  3. Filtro de pesquisa: Adicione duas condições:

    • custbody_jb_synced é false
    • lastmodifieddate após $ns_last_sync_time
  4. Campos de retorno: Selecione internalId, entityId, custentity_sf_id e quaisquer outros campos que mapeiem para o Salesforce.

  5. Clique em Finished.

Etapa 2: Configurar a transformação

  1. Adicione uma etapa de Transformation após a atividade Search do NetSuite.

  2. Defina o esquema de origem como a resposta da Search do NetSuite e o esquema de destino como a estrutura Account do Salesforce.

  3. Mapeie os campos de origem do NetSuite para os campos de destino do Salesforce correspondentes.

  4. Adicione um script no nível raiz que marca cada registro do Salesforce como "sincronizado pelo Jitterbit" e coleta os IDs do NetSuite para a atualização pós-sincronização:

    target.Jitterbit_Synced__c = true;
    $sync_run_time = Now();
    $synced_ns_ids = $synced_ns_ids + If(Length($synced_ns_ids) > 0, ",", "") + Source.internalId;
    

Etapa 3: Configurar a atividade de Upsert do Salesforce

  1. Adicione uma atividade Upsert do Salesforce após a transformação.

  2. Nome: Digite Upsert Salesforce Accounts.

  3. Campo de ID externo: Selecione o campo que armazena o ID interno do NetSuite no Salesforce (por exemplo, NetSuite_ID__c).

  4. Clique em Concluído.

Etapa 4: Escrever o script pós-sincronização

  1. Adicione uma etapa Script após a atividade Upsert do Salesforce.

  2. Digite o seguinte:

    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 = "";
    
  3. Crie uma operação separada chamada Mark NetSuite Records Synced contendo uma atividade Atualizar do NetSuite que define custbody_jb_synced = true em cada ID de registro em synced_ns_ids.

Parte 3: Agendar as operações

Ambas as cadeias são executadas em agendamentos de operação. Para reduzir a chance de ambas as cadeias serem executadas simultaneamente e coletarem gravações em progresso uma da outra, escalone seus horários de início.

  1. Atribua um agendamento à cadeia do Salesforce para NetSuite. Para um intervalo de sincronização de 15 minutos, defina-o para ser executado nos minutos 0, 15, 30 e 45 da hora.

  2. Atribua um agendamento à cadeia do NetSuite para Salesforce e o compense pela metade do intervalo (por exemplo, 7, 22, 37 e 52 minutos da hora).

Para instruções passo a passo sobre como criar e atribuir agendamentos, consulte Agendar uma operação para ser executada automaticamente.

Nota

O escalonamento reduz a sobreposição, mas não a elimina. Se uma execução de sincronização levar mais tempo do que o intervalo de compensação, ambas as cadeias podem ser executadas simultaneamente. Para sincronizações de alto volume, considere adicionar um bloqueio: no início de cada cadeia, leia uma variável de projeto ou entrada do Cloud Datastore chamada sync_lock. Se o bloqueio estiver definido, saia antecipadamente usando RaiseError. Caso contrário, defina o bloqueio antes de prosseguir e limpe-o no script pós-sincronização.

Verificar a integração

  1. Implante e execute a cadeia do Salesforce para NetSuite manualmente.

  2. Nos registros de operação, confirme que os registros foram recuperados do Salesforce e gravados no NetSuite.

  3. No NetSuite, abra um dos registros de clientes sincronizados e confirme que custbody_jb_synced está marcado.

  4. No Salesforce, abra a conta correspondente e confirme que Jitterbit_Synced__c está marcado.

  5. Execute a cadeia do NetSuite para Salesforce. Nos registros, confirme que os registros de Cliente gravados na etapa 2 não aparecem nos resultados de pesquisa do NetSuite. Isso confirma que o filtro de prevenção de loop está funcionando: registros com custbody_jb_synced = true são excluídos.

  6. No NetSuite, modifique um dos registros de clientes sincronizados diretamente. O SuiteScript afterSubmit redefine custbody_jb_synced = false. Execute a cadeia do NetSuite para Salesforce e confirme que a mudança é propagada para o Salesforce.

  7. No Salesforce, confirme que a conta atualizada tem Jitterbit_Synced__c = true após a sincronização. Execute a cadeia do Salesforce para NetSuite e confirme que o registro não aparece nos resultados da consulta, pois foi gravado pela última vez pelo Jitterbit.

Para uma abordagem alternativa para detectar registros alterados sem campos de sinalizador de sincronização, consulte Detectar e desduplicar registros usando funções de hash.