mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-06 02:17:39 +02:00
Transaction rollback fail no longer hides original exception
This commit is contained in:
parent
8870e034e1
commit
1378d3100e
@ -23,7 +23,7 @@ import java.sql.SQLException;
|
|||||||
*
|
*
|
||||||
* @author Rsl1122
|
* @author Rsl1122
|
||||||
*/
|
*/
|
||||||
public class DBOpException extends RuntimeException {
|
public class DBOpException extends IllegalStateException {
|
||||||
|
|
||||||
public DBOpException(String message) {
|
public DBOpException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -108,9 +108,7 @@ public class MySQLDB extends SQLDB {
|
|||||||
hikariConfig.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(10L));
|
hikariConfig.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(10L));
|
||||||
|
|
||||||
this.dataSource = new HikariDataSource(hikariConfig);
|
this.dataSource = new HikariDataSource(hikariConfig);
|
||||||
|
} catch (HikariPool.PoolInitializationException e) {
|
||||||
getConnection();
|
|
||||||
} catch (HikariPool.PoolInitializationException | SQLException e) {
|
|
||||||
throw new DBInitException("Failed to set-up HikariCP Datasource: " + e.getMessage(), e);
|
throw new DBInitException("Failed to set-up HikariCP Datasource: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,11 +124,12 @@ public class MySQLDB extends SQLDB {
|
|||||||
try {
|
try {
|
||||||
setupDataSource();
|
setupDataSource();
|
||||||
// get new connection after restarting pool
|
// get new connection after restarting pool
|
||||||
return dataSource.getConnection();
|
connection = dataSource.getConnection();
|
||||||
} catch (DBInitException e) {
|
} catch (DBInitException e) {
|
||||||
throw new DBOpException("Failed to restart DataSource after a connection was invalid: " + e.getMessage(), e);
|
throw new DBOpException("Failed to restart DataSource after a connection was invalid: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (connection.getAutoCommit()) connection.setAutoCommit(false);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +64,25 @@ public abstract class Transaction {
|
|||||||
try {
|
try {
|
||||||
initializeTransaction(db);
|
initializeTransaction(db);
|
||||||
performOperations();
|
performOperations();
|
||||||
|
if (connection != null) connection.commit();
|
||||||
success = true;
|
success = true;
|
||||||
|
} catch (Exception statementFail) {
|
||||||
|
manageFailure(statementFail); // Throws a DBOpException.
|
||||||
} finally {
|
} finally {
|
||||||
finalizeTransaction();
|
db.returnToPool(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void manageFailure(Exception statementFail) {
|
||||||
|
String failMsg = getClass().getSimpleName() + " failed: " + statementFail.getMessage();
|
||||||
|
try {
|
||||||
|
connection.rollback(savepoint);
|
||||||
|
} catch (SQLException rollbackFail) {
|
||||||
|
throw new DBOpException(failMsg + ", additionally Transaction rollback failed: " + rollbackFail.getMessage(), statementFail);
|
||||||
|
}
|
||||||
|
throw new DBOpException(failMsg + ", Transaction was rolled back.", statementFail);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method for conditional execution.
|
* Override this method for conditional execution.
|
||||||
* <p>
|
* <p>
|
||||||
@ -90,37 +103,12 @@ public abstract class Transaction {
|
|||||||
private void initializeTransaction(SQLDB db) {
|
private void initializeTransaction(SQLDB db) {
|
||||||
try {
|
try {
|
||||||
this.connection = db.getConnection();
|
this.connection = db.getConnection();
|
||||||
// Temporary fix for MySQL Patch task test failing, TODO remove after Auto commit is off for MySQL
|
|
||||||
if (connection.getAutoCommit()) connection.setAutoCommit(false);
|
|
||||||
this.savepoint = connection.setSavepoint();
|
this.savepoint = connection.setSavepoint();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new DBOpException(getClass().getSimpleName() + " initialization failed: " + e.getMessage(), e);
|
throw new DBOpException(getClass().getSimpleName() + " initialization failed: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finalizeTransaction() {
|
|
||||||
try {
|
|
||||||
handleSavepoint();
|
|
||||||
// Temporary fix for MySQL Patch task test failing, TODO remove after Auto commit is off for MySQL
|
|
||||||
if (db.getType() == DBType.MYSQL) connection.setAutoCommit(true);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new DBOpException(getClass().getSimpleName() + " finalization failed: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
if (db != null) db.returnToPool(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleSavepoint() throws SQLException {
|
|
||||||
if (connection == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Commit or rollback the transaction
|
|
||||||
if (success) {
|
|
||||||
connection.commit();
|
|
||||||
} else {
|
|
||||||
connection.rollback(savepoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> T query(Query<T> query) {
|
protected <T> T query(Query<T> query) {
|
||||||
return query.executeQuery(db);
|
return query.executeQuery(db);
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ public class DBPatchMySQLRegressionTest extends DBPatchRegressionTest {
|
|||||||
underTest.setTransactionExecutorServiceProvider(MoreExecutors::newDirectExecutorService);
|
underTest.setTransactionExecutorServiceProvider(MoreExecutors::newDirectExecutorService);
|
||||||
underTest.init();
|
underTest.init();
|
||||||
|
|
||||||
dropAllTables(underTest);
|
dropAllTables();
|
||||||
|
|
||||||
// Initialize database with the old table schema
|
// Initialize database with the old table schema
|
||||||
underTest.executeTransaction(new Transaction() {
|
underTest.executeTransaction(new Transaction() {
|
||||||
@ -122,6 +122,17 @@ public class DBPatchMySQLRegressionTest extends DBPatchRegressionTest {
|
|||||||
insertData(underTest);
|
insertData(underTest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dropAllTables() {
|
||||||
|
underTest.executeTransaction(new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected void performOperations() {
|
||||||
|
execute("DROP DATABASE Plan");
|
||||||
|
execute("CREATE DATABASE Plan");
|
||||||
|
execute("USE Plan");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void closeDatabase() {
|
public void closeDatabase() {
|
||||||
underTest.close();
|
underTest.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user