Fix #61: Connection-Leak in SqliteUnitOfWorkAdapter beheben
Connection wird jetzt in try-with-resources geoeffnet, sodass sie auch dann zuverlaessig geschlossen wird, wenn setAutoCommit(false) wirft. Rollback-Behandlung bleibt unveraendert innerhalb des inneren catch-Blocks. Ebenfalls: korrekten Import fuer DateTimeFormatter ergaenzt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.time.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
+38
-45
@@ -41,58 +41,51 @@ public class SqliteUnitOfWorkAdapter implements UnitOfWorkPort {
|
||||
public void executeInTransaction(Consumer<TransactionOperations> operations) {
|
||||
Objects.requireNonNull(operations, "operations must not be null");
|
||||
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = DriverManager.getConnection(jdbcUrl);
|
||||
try (Connection connection = DriverManager.getConnection(jdbcUrl)) {
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
||||
operations.accept(txOps);
|
||||
try {
|
||||
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
||||
operations.accept(txOps);
|
||||
|
||||
connection.commit();
|
||||
logger.debug("Transaction committed successfully");
|
||||
connection.commit();
|
||||
logger.debug("Transaktion erfolgreich abgeschlossen.");
|
||||
|
||||
} catch (DocumentPersistenceException e) {
|
||||
// Datenbankfehler auf Dokumentebene: Rollback, dann weiterpropagieren
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaktion zurückgerollt (Dokumentfehler): {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
// Unerwarteter Laufzeitfehler: Rollback, dann als Persistenzfehler weitergeben
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaktion zurückgerollt (Laufzeitfehler): {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
throw new DocumentPersistenceException("Transaktion fehlgeschlagen: " + e.getMessage(), e);
|
||||
} catch (SQLException e) {
|
||||
// SQL-Fehler innerhalb der Transaktion: Rollback, dann als Persistenzfehler weitergeben
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaktion zurückgerollt (SQL-Fehler): {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
throw new DocumentPersistenceException("Transaktion fehlgeschlagen: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
} catch (DocumentPersistenceException e) {
|
||||
// Re-throw document-level persistence errors as-is, but still rollback
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaction rolled back due to document error: {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
// Rollback on any RuntimeException and wrap in DocumentPersistenceException
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaction rolled back due to error: {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
}
|
||||
throw new DocumentPersistenceException("Transaction failed: " + e.getMessage(), e);
|
||||
} catch (SQLException e) {
|
||||
// Rollback for any SQL error
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.rollback();
|
||||
logger.debug("Transaction rolled back due to error: {}", e.getMessage());
|
||||
} catch (SQLException rollbackEx) {
|
||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
||||
}
|
||||
}
|
||||
throw new DocumentPersistenceException("Transaction failed: " + e.getMessage(), e);
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
logger.warn("Failed to close connection: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
// Verbindungsaufbau oder setAutoCommit(false) fehlgeschlagen
|
||||
throw new DocumentPersistenceException(
|
||||
"Datenbankverbindung konnte nicht hergestellt werden: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user