O Hologres oferece suporte completo a transações de Data Definition Language (DDL) e suporte parcial a transações de Data Manipulation Language (DML). Por padrão, cada instrução SQL é executada como uma transação independente. Este tópico aborda transações DDL, transações DML mistas (Beta), comportamento de bloqueio e cenários sem suporte a transações.
Instruções de controle de transação
As instruções a seguir controlam os limites das transações no Hologres:
|
Instrução |
Descrição |
|
|
Inicia um bloco de transação. |
|
|
Confirma todas as instruções da transação atual. |
|
|
Interrompe a transação atual e descarta todas as alterações. |
Transações DDL
Agrupe várias instruções DDL em uma única transação para garantir atomicidade. Se alguma instrução falhar, reverta toda a transação para restaurar o estado anterior do schema.
Exemplo: crie e reverta tabelas em uma única transação
BEGIN;
DROP TABLE IF EXISTS ddl_test;
CREATE TABLE ddl_test (
uid TEXT NOT NULL,
name TEXT NOT NULL
);
COMMIT;
Transações DML mistas (Beta)
Disponíveis no Hologres V2.0 e versões posteriores, as transações DML mistas permitem combinar instruções INSERT, UPDATE e DELETE em uma única transação. Isso garante atomicidade e consistência nas gravações de dados, tornando o Hologres adequado para cenários leves de processamento transacional (TP).
As transações DML mistas não aproveitam totalmente os recursos distribuídos do Hologres. Elas oferecem suporte apenas a cargas de trabalho com baixo número de consultas por segundo (QPS) e não são adequadas para cenários de alta concorrência.
Ative transações DML mistas
As transações DML mistas ficam desativadas por padrão. Ative o recurso com o seguinte parâmetro Grand Unified Configuration (GUC):
SET hg_experimental_enable_transaction = on;
Comportamento de reversão
Após ativar o recurso, todas as instruções DML de uma transação são tratadas como uma unidade atômica:
Se qualquer instrução DML falhar, todas as outras instruções da transação serão revertidas automaticamente.
Para descartar manualmente uma transação em andamento, execute
ROLLBACK. Todas as instruções DML da transação serão revertidas.
Exemplo: reversão manual
SET hg_experimental_enable_transaction = on;
BEGIN;
DELETE FROM dml_test;
INSERT INTO dml_test VALUES (1, 'sss');
ROLLBACK;
Comportamento de bloqueio
Em uma transação DML mista, todas as operações — leituras, gravações, exclusões e atualizações — adquirem bloqueios de escrita no nível da tabela. Isso se aplica inclusive às tabelas somente leitura, não apenas àquelas que recebem escrita. Como resultado, múltiplas transações que acessam a mesma tabela são executadas sequencialmente, e não simultaneamente.
Sob alta contenção de bloqueios, o tempo de execução do SQL aumenta significativamente e pode exceder os limites de tempo limite.
Exemplo: transações simultâneas competindo pelo mesmo bloqueio
Considere duas transações simultâneas que leem base_tbl:
-
Usuário A executa:
SET hg_experimental_enable_transaction = on; BEGIN; DELETE FROM dml_test; INSERT INTO dml_test SELECT * FROM base_tbl; COMMIT; -
Usuário B executa:
SET hg_experimental_enable_transaction = on; BEGIN; DELETE FROM dml_test_2; INSERT INTO dml_test_2 SELECT * FROM base_tbl; COMMIT;
Como ambas as transações leem base_tbl, ambas adquirem um bloqueio de escrita sobre ela. A transação do Usuário B aguarda até que a transação do Usuário A seja concluída.
Observações de uso
Transações DML mistas suportam apenas cargas de trabalho de baixo QPS e não são indicadas para cenários de alta concorrência. Execute testes de carga para determinar o teto de QPS da sua carga de trabalho específica.
Caso uma transação inclua operações de escrita e consulta, o desempenho da consulta será inferior ao observado sem transações. A degradação real do desempenho varia conforme o cenário.
Limitações
Não há suporte para transações que contenham instruções DDL e DML simultaneamente. Misturar DDL e DML na mesma transação gera o seguinte erro:
ERROR: INSERT in ddl transaction is not supported now
Exemplo que aciona esse erro:
BEGIN;
DROP TABLE IF EXISTS dml_test;
CREATE TABLE dml_test (
uid TEXT NOT NULL,
name TEXT NOT NULL
);
INSERT INTO dml_test VALUES ('1', 'tom');
COMMIT;