All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.fortnox.reactivewizard.db.transactions.Transaction Maven / Gradle / Ivy

There is a newer version: 24.6.0
Show newest version
package se.fortnox.reactivewizard.db.transactions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Transaction {

    private static final Logger LOG = LoggerFactory.getLogger(Transaction.class);

    private final ConcurrentLinkedQueue statementsToExecute;

    Transaction(List statements) {
        this.statementsToExecute = new ConcurrentLinkedQueue<>(statements);
    }

    /**
     * Execute the transation.
     * @param connection the connection
     * @throws Exception on error
     */
    public void execute(Connection connection) throws Exception {
        try {
            executeTransaction(connection);
            closeConnection(connection);
        } catch (Throwable e) {
            rollback(connection);
            closeConnection(connection);
            throw e;
        }
    }

    private void executeTransaction(Connection connection) throws SQLException {
        connection.setAutoCommit(false);

        for (Batchable statement : batchStatementsWherePossible()) {
            statement.execute(connection);
        }

        connection.commit();
    }

    private LinkedList batchStatementsWherePossible() {
        LinkedList statements = new LinkedList<>();

        for (TransactionStatement statement : statementsToExecute) {
            if (!statements.isEmpty() && statements.peekLast().sameBatch(statement)) {
                Batchable last = statements.pollLast(); // Remove last statement
                statements.add(Batch.batchWrap(last, statement)); // Add in batch with current statement
            } else {
                statements.add(statement);
            }
        }
        return statements;
    }

    private void closeConnection(Connection connection) {
        try {
            connection.setAutoCommit(true);
            connection.close();
        } catch (Exception e) {
            LOG.error("Error closing connection", e);
        }
    }

    private void rollback(Connection connection) {
        try {
            connection.rollback();
        } catch (Exception rollbackException) {
            LOG.error("Rollback failed", rollbackException);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy