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

sqlg3.runtime.TransactionContext Maven / Gradle / Ivy

Go to download

SQLG is a preprocessor and a library that uses code generation to simplify writing JDBC code

There is a newer version: 3.1
Show newest version
package sqlg3.runtime;

import sqlg3.core.IDBCommon;
import sqlg3.core.InformationException;
import sqlg3.core.SQLGException;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;

final class TransactionContext {

    private final GlobalContext global;
    private final SessionContext session;

    private final Object connLock = new Object();
    private Connection connection = null;

    TransactionContext(GlobalContext global, SessionContext session) {
        this.global = global;
        this.session = session;
    }

    Connection getConnection() throws SQLException {
        synchronized (connLock) {
            if (connection == null) {
                connection = session.cman.allocConnection();
            }
            return connection;
        }
    }

    @SuppressWarnings("unchecked")
     T getInterface(Class iface, boolean commitCalls, boolean checkCall) {
        ClassLoader classLoader = iface.getClassLoader();
        return (T) Proxy.newProxyInstance(classLoader, new Class[] {iface}, (proxy, method, args) -> {
            boolean success = false;
            Object result = null;
            Throwable error = null;
            try {
                ImplCache cached = global.getImpl(iface);
                Method daoMethod = cached.dao.getMethod(method.getName(), method.getParameterTypes());
                if (checkCall && session.beforeCall != null) {
                    session.beforeCall.check(daoMethod, args);
                }
                try (GContext ctx = new GContext(global, session, this)) {
                    Object instance = cached.constructor.newInstance(ctx);
                    result = daoMethod.invoke(instance, args);
                    ctx.ok();
                }
                success = true;
            } catch (InvocationTargetException ex) {
                Throwable target = ex.getTargetException();
                if (target instanceof InformationException) {
                    InformationException informationException = (InformationException) target;
                    success = !informationException.error;
                }
                error = target;
            } catch (ReflectiveOperationException ex) {
                error = new SQLGException("Error calling DAO method " + iface.getCanonicalName() + "." + method.getName(), ex);
            } catch (Throwable ex) {
                error = ex;
            }
            if (commitCalls) {
                try {
                    if (success) {
                        commit();
                    } else {
                        rollback();
                    }
                } catch (SQLException ex) {
                    if (error != null) {
                        error.addSuppressed(ex);
                    } else {
                        error = ex;
                    }
                }
            }
            if (error != null) {
                throw error;
            }
            return result;
        });
    }

    private void releaseConnection(SQLException error) throws SQLException {
        try {
            session.cman.releaseConnection(connection);
        } catch (SQLException ex) {
            if (error != null) {
                error.addSuppressed(ex);
            } else {
                error = ex;
            }
        } finally {
            connection = null;
        }
        if (error != null) {
            throw error;
        }
    }

    void commit() throws SQLException {
        synchronized (connLock) {
            if (connection == null)
                return;
            SQLException error = null;
            try {
                connection.commit();
            } catch (SQLException ex) {
                try {
                    connection.rollback();
                } catch (SQLException ex2) {
                    ex.addSuppressed(ex2);
                }
                error = ex;
            } finally {
                releaseConnection(error);
            }
        }
    }

    void rollback() throws SQLException {
        synchronized (connLock) {
            if (connection == null)
                return;
            SQLException error = null;
            try {
                connection.rollback();
            } catch (SQLException ex) {
                error = ex;
            } finally {
                releaseConnection(error);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy