AutoCommitOffWarning.java
/*
*
* The DbUnit Database Testing Framework
* Copyright (C)2002-2026, DbUnit.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.dbunit.database.connection;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.function.Consumer;
import org.dbunit.database.IDatabaseConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Logs one warning, the first time it sees a connection whose autocommit is disabled, for a
* connection dbUnit's own setup and teardown operations will run on. Those operations
* ({@code CLEAN_INSERT}, {@code DELETE_ALL}, ...) do not manage a transaction of their own, and
* {@link org.dbunit.operation.TransactionOperation} refuses a connection whose autocommit is
* already off, so on such a connection their writes are never committed: invisible to other
* connections, and - when the connection is kept across test methods - held as locks a
* database's idle-in-transaction timeout may terminate mid-run.
*
* <p>Used as the {@code onAcquired} hook of a {@link TestScopedConnection} so the check runs
* once per acquired connection at the single acquisition point, whichever path - the annotation
* runtime's setup/teardown handling, or {@link org.dbunit.DefaultPrepAndExpectedTestCase} -
* borrowed it. One instance per lifecycle owner; it warns at most once regardless of how many
* times the connection is (re)acquired.
*
* @author Jeff Jensen
* @since 3.6.0
*/
public class AutoCommitOffWarning implements Consumer<IDatabaseConnection>
{
private final Logger log = LoggerFactory.getLogger(AutoCommitOffWarning.class);
private boolean isAlreadyWarned;
/**
* Warns when {@code connection}'s autocommit is off, unless a warning has already been
* logged by this instance or the autocommit state cannot be read.
*
* @param connection The connection just acquired.
*/
@Override
public void accept(final IDatabaseConnection connection)
{
if (isAlreadyWarned)
{
return;
}
try
{
final Connection jdbcConnection = connection.getConnection();
if (jdbcConnection == null || jdbcConnection.getAutoCommit())
{
return;
}
} catch (final SQLException e)
{
log.debug("AutoCommitOffWarning: could not read the connection's autocommit state",
e);
return;
}
isAlreadyWarned = true;
log.warn("The connection this test's dbUnit setup/teardown operations run on has"
+ " autocommit disabled. Those operations (CLEAN_INSERT, DELETE_ALL, ...) do"
+ " not manage a transaction, and TransactionOperation refuses a non-autocommit"
+ " connection, so the prep and teardown writes are never committed - invisible"
+ " to other connections, and (for a connection shared across test methods)"
+ " held as locks the database's idle-in-transaction timeout may terminate"
+ " mid-run. Use a connection with autocommit enabled.");
}
}