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

jodd.db.DbSession Maven / Gradle / Ivy

// Copyright (c) 2003-2012, Jodd Team (jodd.org). All Rights Reserved.

package jodd.db;

import jodd.db.connection.ConnectionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Set;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;

/**
 * Encapsulates db connection. Initially works in auto-commit mode.
 * May start and work with transactions, after commiting/rolling back
 * DbSession goes back to auto-commit mode.
 * 

* All invoked queries are stored within one session and closed implicitly * on session closing. *

* For managed transaction see DbJtxTransactionManager from jodd-tx. */ public class DbSession { private static final Logger log = LoggerFactory.getLogger(DbSession.class); // ---------------------------------------------------------------- init & close protected final DbManager dbManager = DbManager.getInstance(); protected final ConnectionProvider connectionProvider; protected Connection connection; /** * Creates new database session using default connection provider. */ public DbSession() { this(null); } /** * Creates new database session with default transaction mode and in autocommit mode. */ public DbSession(ConnectionProvider connectionProvider) { if (log.isDebugEnabled()) { log.debug("Creating new db session"); } if (connectionProvider == null) { connectionProvider = dbManager.connectionProvider; if (connectionProvider == null) { throw new DbSqlException("Connection provider is not available."); } } this.connectionProvider = connectionProvider; txActive = false; txMode = dbManager.transactionMode; queries = new HashSet(); } /** * Closes current session and all allocated resources. * All attached queries are closed. If a transaction is still active, exception occurs. * Database connection is returned to the {@link ConnectionProvider}. * Closed session is no longer available for usage. */ public void closeSession() { if (log.isDebugEnabled()) { log.debug("Closing db session"); } List allsexs = null; for (DbQueryBase query : queries) { List sexs = query.closeQuery(); if (sexs != null) { if (allsexs == null) { allsexs = new ArrayList(); } allsexs.addAll(sexs); } } if (connection != null) { if (txActive == true) { throw new DbSqlException("Transaction was not closed before closing the session."); } connectionProvider.closeConnection(connection); connection = null; } queries = null; if (allsexs != null) { throw new DbSqlException("Unable to close DbSession.", allsexs); } } /** * Indicates whether a session is closed. */ public boolean isSessionClosed() { return queries == null; } /** * Returns true if session is open. */ public boolean isSessionOpen() { return queries != null; } // ---------------------------------------------------------------- query /** * Bag of all queries attached to this session. Explicitly closed queries * remains in the set. If null session is closed. * If not null, but empty, session is still considered as open. */ protected Set queries; /** * Returns total number of queries assigned to this session. */ public int getTotalQueries() { if (queries == null) { return 0; } return queries.size(); } /** * Returns current connection. */ public Connection getConnection() { return connection; } /** * Attaches a new {@link DbQuery}. May be invoked both inside and outside of transaction. */ protected void attachQuery(DbQueryBase query) { checkOpenSession(); openConnectionForQuery(); queries.add(query); } /** * Detach used {@link DbQuery}. Usually invoked by {@link jodd.db.DbQuery#close()}. */ protected void detachQuery(DbQueryBase query) { queries.remove(query); } /** * Opens connection in auto-commit mode, if already not opened. */ protected void openConnectionForQuery() { if (connection == null) { connection = connectionProvider.getConnection(); txActive = false; // txAction should already be false try { connection.setAutoCommit(true); } catch (SQLException sex) { throw new DbSqlException("Unable to open non-transactional connection.", sex); } } } // ---------------------------------------------------------------- transaction protected boolean txActive; protected DbTransactionMode txMode; /** * Indicate whether a transaction is in progress. */ public boolean isTransactionActive() { return txActive; } /** * Opens a transaction. */ protected void openTx() { if (connection == null) { connection = connectionProvider.getConnection(); } txActive = true; try { connection.setAutoCommit(false); if (txMode.getIsolation() != DbTransactionMode.ISOLATION_DEFAULT) { connection.setTransactionIsolation(txMode.getIsolation()); } connection.setReadOnly(txMode.isReadOnly()); } catch (SQLException sex) { throw new DbSqlException("Unable to open and prepare transaction.", sex); } } /** * Closes current transaction. */ protected void closeTx() { txActive = false; try { connection.setAutoCommit(true); } catch (SQLException sex) { throw new DbSqlException("Unable to prepare connection", sex); } } /** * Starts a transaction. */ public void beginTransaction(DbTransactionMode mode) { if (log.isDebugEnabled()) { log.debug("Beginning transaction"); } checkClosedTx(); this.txMode = mode; openTx(); } /** * Starts transaction with default transaction mode. */ public void beginTransaction() { beginTransaction(dbManager.transactionMode); } /** * Commit the current transaction, writing any unflushed changes to the database. * Transaction mode is closed. */ public void commitTransaction() { if (log.isDebugEnabled()) { log.debug("Committing transaction"); } checkActiveTx(); try { connection.commit(); } catch (SQLException sex) { throw new DbSqlException("Unable to commit transaction.", sex); } finally { closeTx(); } } /** * Roll back the current transaction. Transaction mode is closed. */ public void rollbackTransaction() { if (log.isDebugEnabled()) { log.debug("Rolling-back transaction"); } checkActiveTx(); try { connection.rollback(); } catch (SQLException sex) { throw new DbSqlException("Unable to rollback transaction.", sex); } finally { closeTx(); } } // ---------------------------------------------------------------- checking protected void checkOpenSession() { if (queries == null) { throw new DbSqlException("Session is closed."); } } protected void checkClosedTx() { checkOpenSession(); if (txActive == true) { throw new DbSqlException("Transaction already started for this session."); } } protected void checkActiveTx() { checkOpenSession(); if (txActive == false) { throw new DbSqlException("Transaction not available for this session."); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy