SQLite Java: Transação

Resumo : neste tutorial, mostraremos como usar transações JDBC para gerenciar transações no banco de dados SQLite.

Banco de dados de amostra para demonstração de transação

Antes de iniciar com Java, criaremos duas novas tabelas no banco de dados test.db.

  1. A materialstabela armazena o mestre de materiais.
  2. A inventorytabela armazena o relacionamento entre a tabela warehousese materials. Além disso, a inventorytabela possui a qtycoluna que armazena os dados do estoque.

As instruções a seguir criam as tabelas materialse inventory.

CREATE TABLE IF NOT EXISTS materials (
	id integer PRIMARY KEY,
	description text NOT NULL
);

CREATE TABLE IF NOT EXISTS inventory (
	warehouse_id integer,
	material_id integer,
	qty real,
	PRIMARY KEY (warehouse_id, material_id),
	FOREIGN KEY (warehouse_id) REFERENCES warehouses (id),
	FOREIGN KEY (material_id) REFERENCES materials (id)
);Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )

O diagrama a seguir ilustra as tabelas e seu relacionamento.

Demonstração de tabelas de transação SQLite Java

O que é uma transação de banco de dados

Uma transação representa um conjunto de operações executadas como uma única unidade de trabalho. Isso significa que se alguma operação do conjunto falhar, o SQLite aborta outras operações e reverte os dados ao seu estado inicial.

Uma transação possui quatro atributos principais, conhecidos como ACID.

  • A letra A significa atomicidade. Isso significa que cada transação deve ser tudo ou nada. Se alguma operação na transação falhar, o estado do banco de dados permanece inalterado.
  • A letra C significa consistência. Ele garante que qualquer transação trará os dados do banco de dados de um estado válido para outro.
  • A letra I significa isolamento. Isso é para controle de simultaneidade. Ele garante que todas as execuções simultâneas de transações produzam o mesmo resultado como se fossem executadas sequencialmente.
  • A letra D significa durabilidade. Isso significa que quando a transação for confirmada, ela permanecerá intacta, independentemente de quaisquer erros, como perda de energia.

Exemplo de transação Java SQLite

Quando você se conecta a um banco de dados SQLite, o modo padrão é confirmação automática. Isso significa que cada consulta emitida ao banco de dados SQLite é automaticamente confirmada.

Para desabilitar o modo de confirmação automática, você usa o setAutoCommit()método do Connectionobjeto da seguinte forma:

 conn.setAutoCommit(false);Linguagem de código:  Java  ( java )

Para confirmar o trabalho, você usa o método commit do Connectionobjeto.

conn.commit();Linguagem de código:  Java  ( java )

Caso ocorra uma falha no meio da transação, você sempre pode usar o rollback()método para reverter a transação.

conn.rollback();Linguagem de código:  Java  ( java )

O programa a seguir adiciona novo material à tabela de materiais e também lança o estoque. Colocamos ambas as operações na mesma transação.

package net.sqlitetutorial;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *
 * @author tutorials.acervolima.com
 */
public class TransactionApp {

    /**
     * Connect to the test.db database
     *
     * @return the Connection object
     */
    private Connection connect() {
        // SQLite connection string
        String url = "jdbc:sqlite:C://sqlite/db/test.db";
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }

    /**
     * Create a new material and add initial quantity to the warehouse
     *
     * @param material
     * @param warehouseId
     * @param qty
     */
    public void addInventory(String material, int warehouseId, double qty) {
        // SQL for creating a new material
        String sqlMaterial = "INSERT INTO materials(description) VALUES(?)";
        
        // SQL for posting inventory
        String sqlInventory = "INSERT INTO inventory(warehouse_id,material_id,qty)"
                + "VALUES(?,?,?)";

        ResultSet rs = null;
        Connection conn = null;
        PreparedStatement pstmt1 = null, pstmt2 = null;
        
        try {
            // connect to the database
            conn = this.connect();
            if(conn == null)
                return;
            
            // set auto-commit mode to false
            conn.setAutoCommit(false);
            
            // 1. insert a new material
            pstmt1 = conn.prepareStatement(sqlMaterial,
                    Statement.RETURN_GENERATED_KEYS);

            pstmt1.setString(1, material);
            int rowAffected = pstmt1.executeUpdate();

            // get the material id
            rs = pstmt1.getGeneratedKeys();
            int materialId = 0;
            if (rs.next()) {
                materialId = rs.getInt(1);
            }

            if (rowAffected != 1) {
                conn.rollback();
            }
            // 2. insert the inventory
            pstmt2 = conn.prepareStatement(sqlInventory);
            pstmt2.setInt(1, warehouseId);
            pstmt2.setInt(2, materialId);
            pstmt2.setDouble(3, qty);
            // 
            pstmt2.executeUpdate();
            // commit work
            conn.commit();

        } catch (SQLException e1) {
            try {
                if (conn != null) {
                    conn.rollback();
                }
            } catch (SQLException e2) {
                System.out.println(e2.getMessage());
            }
            System.out.println(e1.getMessage());
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (pstmt1 != null) {
                    pstmt1.close();
                }
                if (pstmt2 != null) {
                    pstmt2.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e3) {
                System.out.println(e3.getMessage());
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        TransactionApp app = new TransactionApp();
        app.addInventory("HP Laptop", 3, 100);
    }

}Linguagem de código:  Java  ( java )

Para verificar o resultado, você pode consultar os dados da materialstabela and inventoryusando a cláusula inner join da seguinte maneira:

SELECT
	name,
	description,
	qty
FROM
	materials
INNER JOIN inventory ON inventory.material_id = materials.id
INNER JOIN warehouses ON warehouses.id = inventory.warehouse_id;Linguagem de código:  SQL (linguagem de consulta estruturada)  ( sql )
Exemplo de transação SQLite Java

Neste tutorial, você aprendeu como gerenciar a transação em SQLite usando Java JDBC.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *