<commit_before>package com.cloud.utils.db;

import com.cloud.utils.Pair;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.mgmt.JmxUtil;

import javax.sql.DataSource;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.KeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Transaction abstracts away the Connection object in JDBC. It allows the following things that the Connection object
 * does not.
 * <p>
 * 1. Transaction can be started at an entry point and whether the DB actions should be auto-commit or not determined at
 * that point. 2. DB Connection is allocated only when it is needed. 3. Code does not need to know if a transaction has
 * been started or not. It just starts/ends a transaction and we resolve it correctly with the previous actions.
 * <p>
 * Note that this class is not synchronous but it doesn't need to be because it is stored with TLS and is one per
 * thread. Use appropriately.
 */
public class TransactionLegacy implements Closeable {
    public static final short CLOUD_DB = 0;
    public static final short USAGE_DB = 1;
    public static final short CONNECTED_DB = -1;
    private static final Logger logger = LoggerFactory.getLogger(TransactionLegacy.class);
    private static final String DB_CONNECTION_SCHEME = "jdbc:mariadb";
    private static final ThreadLocal<TransactionLegacy> tls = new ThreadLocal<>();
    private static final String START_TXN = "start_txn";
    private static final String CURRENT_TXN = "current_txn";
    private static final String CREATE_TXN = "create_txn";
    private static final String CREATE_CONN = "create_conn";
    private static final String STATEMENT = "statement";
    private static final String ATTACHMENT = "attachment";
    private static final AtomicLong s_id = new AtomicLong();
    private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl();
    private static DataSource s_ds;
    private static DataSource s_usageDS;
    private static boolean s_dbHAEnabled;

    static {
        try {
            JmxUtil.registerMBean("Transaction", "Transaction", s_mbean);
        } catch (final Exception e) {
            logger.error("Unable to register mbean for transaction", e);
        }
    }

    static {
        // Initialize with assumed db.properties file
        initDataSource(DbProperties.getDbProperties());
    }

    private final LinkedList<StackElement> _stack;
    private final LinkedList<Pair<String, Long>> _lockTimes = new LinkedList<>();
    private long _id;
    private String _name;
    private Connection _conn;
    private boolean _txn;
    private short _dbId;
    private long _txnTime;
    private Statement _stmt;
    private String _creator;

    private TransactionLegacy(final String name, final boolean forLocking, final short databaseId) {
        _name = name;
        _conn = null;
        _stack = new LinkedList<>();
        _txn = false;
        _dbId = databaseId;
        _id = s_id.incrementAndGet();
        _creator = Thread.currentThread().getName();
    }

    private TransactionLegacy() {
        _name = null;
        _conn = null;
        _stack = null;
        _txn = false;
        _dbId = -1;
    }

    public static TransactionLegacy currentTxn() {
        return currentTxn(true);
    }

    protected static TransactionLegacy currentTxn(final boolean check) {
        final TransactionLegacy txn = tls.get();
        if (check) {
            assert txn != null : "No Transaction on stack.  Did you mark the method with @DB?";
        }
        return txn;
    }

    public static TransactionLegacy open(final short databaseId) {
        String name = buildName();
        if (name == null) {
            name = CURRENT_TXN;
        }
        return open(name, databaseId, true);
    }

    public static TransactionLegacy open(final String name) {
        return open(name, TransactionLegacy.CLOUD_DB, false);
    }

    public static TransactionLegacy open(final String name, final short databaseId, final boolean forceDbChange) {
        TransactionLegacy txn = tls.get();
        boolean isNew = false;
        if (txn == null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating the transaction: " + name);
            }
            txn = new TransactionLegacy(name, false, databaseId);
            tls.set(txn);
            isNew = true;
        } else if (forceDbChange) {
            final short currentDbId = txn.getDatabaseId();
            if (currentDbId != databaseId) {
                // we need to end the current transaction and switch databases
                txn.close(txn.getName());

                txn = new TransactionLegacy(name, false, databaseId);
                tls.set(txn);
                isNew = true;
            }
        }

        txn.takeOver(name, false);
        if (isNew) {
            s_mbean.addTransaction(txn);
        }
        return txn;
    }

    public static Connection getStandaloneConnection() {
        try {
            return getStandaloneConnectionWithException();
        } catch (final SQLException e) {
            logger.error("Unexpected exception: ", e);
            return null;
        }
    }

    public static Connection getStandaloneConnectionWithException() throws SQLException {
        final Connection conn = s_ds.getConnection();
        if (logger.isTraceEnabled()) {
            logger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn));
        }
        return conn;
    }<commit_msg>Refresh MySQl connection when it's disconnected<commit_after>package com.cloud.utils.db;

import com.cloud.utils.Pair;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.mgmt.JmxUtil;

import javax.sql.DataSource;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.KeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.StackKeyedObjectPoolFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Transaction abstracts away the Connection object in JDBC. It allows the following things that the Connection object
 * does not.
 * <p>
 * 1. Transaction can be started at an entry point and whether the DB actions should be auto-commit or not determined at
 * that point. 2. DB Connection is allocated only when it is needed. 3. Code does not need to know if a transaction has
 * been started or not. It just starts/ends a transaction and we resolve it correctly with the previous actions.
 * <p>
 * Note that this class is not synchronous but it doesn't need to be because it is stored with TLS and is one per
 * thread. Use appropriately.
 */
public class TransactionLegacy implements Closeable {
    public static final short CLOUD_DB = 0;
    public static final short USAGE_DB = 1;
    public static final short CONNECTED_DB = -1;
    private static final Logger logger = LoggerFactory.getLogger(TransactionLegacy.class);
    private static final String DB_CONNECTION_SCHEME = "jdbc:mariadb";
    private static final ThreadLocal<TransactionLegacy> tls = new ThreadLocal<>();
    private static final String START_TXN = "start_txn";
    private static final String CURRENT_TXN = "current_txn";
    private static final String CREATE_TXN = "create_txn";
    private static final String CREATE_CONN = "create_conn";
    private static final String STATEMENT = "statement";
    private static final String ATTACHMENT = "attachment";
    private static final AtomicLong s_id = new AtomicLong();
    private static final TransactionMBeanImpl s_mbean = new TransactionMBeanImpl();
    private static DataSource s_ds;
    private static DataSource s_usageDS;
    private static boolean s_dbHAEnabled;

    static {
        try {
            JmxUtil.registerMBean("Transaction", "Transaction", s_mbean);
        } catch (final Exception e) {
            logger.error("Unable to register mbean for transaction", e);
        }
    }

    static {
        // Initialize with assumed db.properties file
        initDataSource(DbProperties.getDbProperties());
    }

    private final LinkedList<StackElement> _stack;
    private final LinkedList<Pair<String, Long>> _lockTimes = new LinkedList<>();
    private long _id;
    private String _name;
    private Connection _conn;
    private boolean _txn;
    private short _dbId;
    private long _txnTime;
    private Statement _stmt;
    private String _creator;

    private TransactionLegacy(final String name, final boolean forLocking, final short databaseId) {
        _name = name;
        _conn = null;
        _stack = new LinkedList<>();
        _txn = false;
        _dbId = databaseId;
        _id = s_id.incrementAndGet();
        _creator = Thread.currentThread().getName();
    }

    private TransactionLegacy() {
        _name = null;
        _conn = null;
        _stack = null;
        _txn = false;
        _dbId = -1;
    }

    public static TransactionLegacy currentTxn() {
        return currentTxn(true);
    }

    protected static TransactionLegacy currentTxn(final boolean check) {
        final TransactionLegacy txn = tls.get();
        if (check) {
            assert txn != null : "No Transaction on stack.  Did you mark the method with @DB?";
        }
        return txn;
    }

    public static TransactionLegacy open(final short databaseId) {
        String name = buildName();
        if (name == null) {
            name = CURRENT_TXN;
        }
        return open(name, databaseId, true);
    }

    public static TransactionLegacy open(final String name) {
        return open(name, TransactionLegacy.CLOUD_DB, false);
    }

    public static TransactionLegacy open(final String name, final short databaseId, final boolean forceDbChange) {
        TransactionLegacy txn = tls.get();
        boolean isNew = false;
        if (txn == null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating the transaction: " + name);
            }
            txn = new TransactionLegacy(name, false, databaseId);
            tls.set(txn);
            isNew = true;
        } else if (forceDbChange) {
            final short currentDbId = txn.getDatabaseId();
            if (currentDbId != databaseId) {
                // we need to end the current transaction and switch databases
                txn.close(txn.getName());

                txn = new TransactionLegacy(name, false, databaseId);
                tls.set(txn);
                isNew = true;
            }
        }

        txn.checkConnection();
        txn.takeOver(name, false);
        if (isNew) {
            s_mbean.addTransaction(txn);
        }
        return txn;
    }

    public void checkConnection() {
        try {
            if (_conn != null && !_conn.isValid(3)) {
                _conn = null;
            }
        } catch (SQLException e) {
            _conn = null;
        }
    }

    public static Connection getStandaloneConnection() {
        try {
            return getStandaloneConnectionWithException();
        } catch (final SQLException e) {
            logger.error("Unexpected exception: ", e);
            return null;
        }
    }

    public static Connection getStandaloneConnectionWithException() throws SQLException {
        final Connection conn = s_ds.getConnection();
        if (logger.isTraceEnabled()) {
            logger.trace("Retrieving a standalone connection: dbconn" + System.identityHashCode(conn));
        }
        return conn;
    }
{'fraction_non_alphanumeric': 0.08310784692694241, 'fraction_numerical': 0.0014688828759180518, 'mean_word_length': 2.7924362357080037, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6964170', 'n_tokens_mistral': 3548, 'n_tokens_neox': 3458, 'n_words': 1091}