SOQL Locking Records: Como e Quando Usar o FOR UPDATE no Salesforce

14/12/2025

Em ambientes onde múltiplos processos atuam sobre os mesmos dados ao mesmo tempo, conflitos de concorrência podem se tornar um problema real. Atualizações simultâneas, registros sendo manipulados por fluxos paralelos ou automações complexas em Apex podem gerar inconsistências, falhas silenciosas ou até interrupções inesperadas no processamento.

É justamente para esses cenários que o SOQL Locking Records existe. Ele permite bloquear registros temporariamente durante uma transação Apex, garantindo que nenhum outro processo os altere enquanto você executa uma lógica crítica.
Neste artigo, vamos explorar como funciona o locking no Salesforce, quando usá-lo com segurança e quais boas práticas ajudam a evitar deadlocks.

O que é Locking Records no Salesforce

O Locking Records é um mecanismo de bloqueio de registros acionado diretamente por uma consulta SOQL por meio da cláusula FOR UPDATE. Ao utilizá-la, todos os registros retornados pela consulta ficam bloqueados até o final da transação Apex.

Isso significa que:

  • Nenhum outro processo pode alterar esses registros enquanto o Apex estiver em execução.

  • Não é necessário fazer commit manual.

    • Se a transação falhar, todas as alterações são revertidas.

    • Se ela concluir com sucesso, o Salesforce realiza o commit automaticamente.

Esse recurso é extremamente útil em operações críticas que dependem da integridade total dos dados durante o processamento.

apex
for (Account acc : [
    SELECT Id
    FROM Account
    WHERE CreatedDate = THIS_MONTH
    FOR UPDATE
]) {
    // Sua lógica aqui
}

Ao executar essa consulta:

  • Todos os registros retornados são bloqueados imediatamente.

  • Outros processos Apex ou automações que tentarem atualizá-los receberão uma exceção.

Atenção: ORDER BY não é permitido

O Salesforce não permite usar ORDER BY em consultas que tenham FOR UPDATE.
Isso protege o tempo de bloqueio, pois ordenar registros aumenta o tempo de execução e prolonga o período de lock — o oposto daquilo que se deseja ao utilizar esse recurso.

O que acontece se o registro já estiver bloqueado?

Existem duas situações comuns:

1. QueryException

Ocorre quando sua SOQL tenta bloquear um registro que já está bloqueado por outra transação ativa.

2. DmlException

Surge quando você tenta realizar um update em um registro que está bloqueado por outra transação.

Um exemplo com tratamento adequado:

apex
try {
    List accts = [
        SELECT Id, Name 
        FROM Account 
        WHERE CreatedDate = THIS_MONTH
        FOR UPDATE
    ];
    
    for (Account acc : accts) {
        acc.Name = acc.Name + ' - Processado';
    }

    update accts;

} catch (QueryException qe) {
    System.debug('Erro ao tentar bloquear registros: ' + qe.getMessage());
} catch (DmlException de) {
    System.debug('Erro ao atualizar registros bloqueados: ' + de.getMessage());
}

Evitando Deadlocks

Assim como qualquer sistema transacional, o Apex pode enfrentar deadlocks — situações onde uma transação aguarda outra indefinidamente.

Para minimizar riscos, o runtime do Salesforce segue regras de bloqueio:

  • Registros pai são bloqueados antes dos registros filhos.

  • Registros do mesmo objeto são bloqueados sempre na ordem do ID.

Apesar dessas proteções, a recomendação é clara:

Realize o lock somente nos registros que realmente serão alterados.

Bloquear mais registros do que o necessário aumenta o risco de espera e de deadlock.

Boas práticas ao usar SOQL Locking Records

Para garantir o uso seguro e eficiente, considere as seguintes recomendações:

1. Não utilize FOR UPDATE em consultas amplas

Evite aplicar lock em centenas ou milhares de registros de forma desnecessária.

2. Bloqueie o mais tarde possível e libere o mais cedo possível

Priorize trechos de código curtos e objetivos.

3. Combine com execução assíncrona

Usar métodos future, Queueable ou Batch Apex pode evitar conflitos em momentos de pico, pois o Salesforce gerencia a janela de execução ideal.

4. Evite ORDER BY

Conforme mencionado, essa operação aumenta o tempo de bloqueio e não é permitida com FOR UPDATE.

5. Sempre trate QueryException e DmlException

Erros de concorrência são comuns em grandes organizações.

Quando usar (e quando evitar) o Locking Records

Use quando:

  • Múltiplos processos podem atualizar os mesmos registros quase simultaneamente.

  • Sua lógica depende de integridade total durante o processamento.

  • Você precisa evitar leituras ou gravações inconsistentes entre automações.

Evite quando:

  • A consulta retorna um número muito grande de registros.

  • Os dados não serão alterados.

  • A lógica não é crítica a ponto de exigir bloqueio.


Conclusão

O SOQL Locking Records é uma ferramenta poderosa para garantir integridade em operações críticas no Salesforce. Embora o próprio CRM gerencie muito bem cenários de concorrência, existem momentos em que o bloqueio explícito é necessário para evitar conflitos, falhas de atualização e inconsistências.

Mais importante do que saber como utilizar o FOR UPDATE é entender quando ele realmente deve ser aplicado.
Use com parcimônia, trate exceções adequadamente e considere sempre a execução assíncrona quando possível.

A transformação que sua empresa precisa começa agora

Consultoria especializada, foco na experiência do cliente e implementação de soluções personalizadas em Salesforce para o seu negócio.

Inscreva-se na Soublog

Assine nossa newsletter e receba em seu e-mail conteúdos exclusivos sobre tecnologia, usabilidade e transformação digital. Fique atualizado com as principais tendências e novidades do mercado!