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.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.time.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|||||||
+20
-27
@@ -41,58 +41,51 @@ public class SqliteUnitOfWorkAdapter implements UnitOfWorkPort {
|
|||||||
public void executeInTransaction(Consumer<TransactionOperations> operations) {
|
public void executeInTransaction(Consumer<TransactionOperations> operations) {
|
||||||
Objects.requireNonNull(operations, "operations must not be null");
|
Objects.requireNonNull(operations, "operations must not be null");
|
||||||
|
|
||||||
Connection connection = null;
|
try (Connection connection = DriverManager.getConnection(jdbcUrl)) {
|
||||||
try {
|
|
||||||
connection = DriverManager.getConnection(jdbcUrl);
|
|
||||||
connection.setAutoCommit(false);
|
connection.setAutoCommit(false);
|
||||||
|
|
||||||
|
try {
|
||||||
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
||||||
operations.accept(txOps);
|
operations.accept(txOps);
|
||||||
|
|
||||||
connection.commit();
|
connection.commit();
|
||||||
logger.debug("Transaction committed successfully");
|
logger.debug("Transaktion erfolgreich abgeschlossen.");
|
||||||
|
|
||||||
} catch (DocumentPersistenceException e) {
|
} catch (DocumentPersistenceException e) {
|
||||||
// Re-throw document-level persistence errors as-is, but still rollback
|
// Datenbankfehler auf Dokumentebene: Rollback, dann weiterpropagieren
|
||||||
if (connection != null) {
|
|
||||||
try {
|
try {
|
||||||
connection.rollback();
|
connection.rollback();
|
||||||
logger.debug("Transaction rolled back due to document error: {}", e.getMessage());
|
logger.debug("Transaktion zurückgerollt (Dokumentfehler): {}", e.getMessage());
|
||||||
} catch (SQLException rollbackEx) {
|
} catch (SQLException rollbackEx) {
|
||||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// Rollback on any RuntimeException and wrap in DocumentPersistenceException
|
// Unerwarteter Laufzeitfehler: Rollback, dann als Persistenzfehler weitergeben
|
||||||
if (connection != null) {
|
|
||||||
try {
|
try {
|
||||||
connection.rollback();
|
connection.rollback();
|
||||||
logger.debug("Transaction rolled back due to error: {}", e.getMessage());
|
logger.debug("Transaktion zurückgerollt (Laufzeitfehler): {}", e.getMessage());
|
||||||
} catch (SQLException rollbackEx) {
|
} catch (SQLException rollbackEx) {
|
||||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||||
}
|
}
|
||||||
}
|
throw new DocumentPersistenceException("Transaktion fehlgeschlagen: " + e.getMessage(), e);
|
||||||
throw new DocumentPersistenceException("Transaction failed: " + e.getMessage(), e);
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
// Rollback for any SQL error
|
// SQL-Fehler innerhalb der Transaktion: Rollback, dann als Persistenzfehler weitergeben
|
||||||
if (connection != null) {
|
|
||||||
try {
|
try {
|
||||||
connection.rollback();
|
connection.rollback();
|
||||||
logger.debug("Transaction rolled back due to error: {}", e.getMessage());
|
logger.debug("Transaktion zurückgerollt (SQL-Fehler): {}", e.getMessage());
|
||||||
} catch (SQLException rollbackEx) {
|
} catch (SQLException rollbackEx) {
|
||||||
logger.error("Failed to rollback transaction: {}", rollbackEx.getMessage(), rollbackEx);
|
logger.error("Rollback fehlgeschlagen: {}", rollbackEx.getMessage(), rollbackEx);
|
||||||
}
|
}
|
||||||
|
throw new DocumentPersistenceException("Transaktion fehlgeschlagen: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
throw new DocumentPersistenceException("Transaction failed: " + e.getMessage(), e);
|
|
||||||
} finally {
|
} catch (DocumentPersistenceException e) {
|
||||||
if (connection != null) {
|
throw e;
|
||||||
try {
|
|
||||||
connection.close();
|
|
||||||
} catch (SQLException e) {
|
} 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