Resumo : neste tutorial mostraremos como usar a transação SQLite para garantir a integridade e confiabilidade dos dados.
SQLite e ÁCIDO
SQLite é um banco de dados transacional em que todas as alterações e consultas são atômicas, consistentes, isoladas e duráveis (ACID).
SQLite garante que todas as transações sejam compatíveis com ACID, mesmo se a transação for interrompida por uma falha do programa, despejo do sistema operacional ou falha de energia no computador.
- Um tomic: uma transação deve ser atômica. Isso significa que uma mudança não pode ser dividida em outras menores. Quando você confirma uma transação, toda a transação é aplicada ou não.
- Consistente : uma transação deve garantir a mudança do banco de dados de um estado válido para outro. Quando uma transação inicia e executa uma instrução para modificar dados, o banco de dados se torna inconsistente. No entanto, quando a transação é confirmada ou revertida, é importante que a transação mantenha o banco de dados consistente.
- Solução : uma transação pendente realizada por uma sessão deve ser isolada das demais sessões. Quando uma sessão inicia uma transação e executa a instrução
INSERT
ouUPDATE
para alterar os dados, essas alterações são visíveis apenas para a sessão atual, e não para outras. Por outro lado, as alterações confirmadas por outras sessões após o início da transação não devem ser visíveis para a sessão atual. - Durável: se uma transação for confirmada com sucesso, as alterações deverão ser permanentes no banco de dados, independentemente da condição, como falha de energia ou falha do programa. Pelo contrário, se o programa travar antes da transação ser confirmada, a alteração não deverá persistir.
Instruções de transação SQLite
Por padrão, o SQLite opera em modo de confirmação automática. Isso significa que para cada comando, o SQLite inicia, processa e confirma a transação automaticamente.
Para iniciar uma transação explicitamente, você usa as seguintes etapas:
Primeiro, abra uma transação emitindo o BEGIN TRANSACTION
comando.
BEGIN TRANSACTION;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Depois de executar a instrução BEGIN TRANSACTION
, a transação é aberta até que seja explicitamente confirmada ou revertida.
Segundo, emita instruções SQL para selecionar ou atualizar dados no banco de dados. Observe que a alteração só é visível para a sessão atual (ou cliente).
Terceiro, confirme as alterações no banco de dados usando a instrução COMMIT
ou COMMIT TRANSACTION
.
COMMIT;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Se não quiser salvar as alterações, você pode reverter usando a instrução ROLLBACK
ou :ROLLBACK TRANSACTION
ROLLBACK;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Exemplo de transação SQLite
Criaremos duas novas tabelas: accounts
e account_changes
para demonstração.
A accounts
tabela armazena dados sobre os números das contas e seus saldos. A account_changes
tabela armazena as alterações das contas.
Primeiro, crie as accounts
tabelas account_changes
e usando as seguintes CREATE TABLE
instruções:
CREATE TABLE accounts (
account_no INTEGER NOT NULL,
balance DECIMAL NOT NULL DEFAULT 0,
PRIMARY KEY(account_no),
CHECK(balance >= 0)
);
CREATE TABLE account_changes (
change_no INT NOT NULL PRIMARY KEY,
account_no INTEGER NOT NULL,
flag TEXT NOT NULL,
amount DECIMAL NOT NULL,
changed_at TEXT NOT NULL
);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, insira alguns dados de amostra na accounts
tabela.
INSERT INTO accounts (account_no,balance)
VALUES (100,20100);
INSERT INTO accounts (account_no,balance)
VALUES (200,10100);
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Terceiro, consulte os dados da accounts
tabela:
SELECT * FROM accounts;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Quarto, transfira 1.000 da conta 100 para 200 e registre as alterações na tabela account_changes
em uma única transação.
BEGIN TRANSACTION;
UPDATE accounts
SET balance = balance - 1000
WHERE account_no = 100;
UPDATE accounts
SET balance = balance + 1000
WHERE account_no = 200;
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(100,'-',1000,datetime('now'));
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(200,'+',1000,datetime('now'));
COMMIT;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Quinto, consulte os dados da accounts
tabela:
SELECT * FROM accounts;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Como você pode ver, os saldos foram atualizados com sucesso.
Sexto, consulte o conteúdo da account_changes
tabela:
SELECT * FROM account_changes;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Vejamos outro exemplo de reversão de uma transação.
Primeiro, tente deduzir 20.000 da conta 100:
BEGIN TRANSACTION;
UPDATE accounts
SET balance = balance - 20000
WHERE account_no = 100;
INSERT INTO account_changes(account_no,flag,amount,changed_at)
VALUES(100,'-',20000,datetime('now'));
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
SQLite emitiu um erro devido a saldo insuficiente:
[SQLITE_CONSTRAINT] Abort due to constraint violation (CHECK constraint failed: accounts)
Linguagem de código: CSS ( css )
No entanto, o log foi salvo na account_changes
tabela:
SELECT * FROM account_changes;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Segundo, reverta a transação usando a ROLLBACK
instrução:
ROLLBACK;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Por fim, consulte os dados da account_changes
tabela, você verá que a alteração nº 3 não existe mais:
SELECT * FROM account_changes;
Linguagem de código: SQL (linguagem de consulta estruturada) ( sql )
Neste tutorial, você aprendeu como lidar com transações SQLite usando as instruções BEGIN TRANSACTION
, COMMIT
e ROLLBACK
para controlar as transações no banco de dados SQLite.