Compare commits
2 Commits
4bbee57d41
...
c137d9e02e
| Author | SHA1 | Date | |
|---|---|---|---|
| c137d9e02e | |||
| ea8b94acc7 |
+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;
|
||||||
|
|||||||
+38
-45
@@ -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);
|
||||||
|
|
||||||
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
try {
|
||||||
operations.accept(txOps);
|
TransactionOperationsImpl txOps = new TransactionOperationsImpl(connection);
|
||||||
|
operations.accept(txOps);
|
||||||
|
|
||||||
connection.commit();
|
connection.commit();
|
||||||
logger.debug("Transaction committed successfully");
|
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) {
|
} 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;
|
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) {
|
} catch (SQLException e) {
|
||||||
// Rollback for any SQL error
|
// Verbindungsaufbau oder setAutoCommit(false) fehlgeschlagen
|
||||||
if (connection != null) {
|
throw new DocumentPersistenceException(
|
||||||
try {
|
"Datenbankverbindung konnte nicht hergestellt werden: " + e.getMessage(), e);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -8,6 +8,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.in.HistoricalDocumentContext;
|
import de.gecheckt.pdf.umbenenner.application.port.in.HistoricalDocumentContext;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.in.ResolveHistoricalDocumentContextUseCase;
|
import de.gecheckt.pdf.umbenenner.application.port.in.ResolveHistoricalDocumentContextUseCase;
|
||||||
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentPersistenceException;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordLookupResult;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordLookupResult;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentTerminalFinalFailure;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentTerminalFinalFailure;
|
||||||
@@ -28,10 +29,11 @@ import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;
|
|||||||
* <li>In allen anderen Fällen (unbekannt, verarbeitbar) sowie bei erwarteten technischen
|
* <li>In allen anderen Fällen (unbekannt, verarbeitbar) sowie bei erwarteten technischen
|
||||||
* Abfragefehlern: leeres {@link Optional}.</li>
|
* Abfragefehlern: leeres {@link Optional}.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* Unerwartete {@link RuntimeException}s aus dem Repository werden geloggt (WARN) und
|
* {@link DocumentPersistenceException}s aus dem Repository werden geloggt (WARN) und
|
||||||
* weiterpropagiert. Erwartete Lookup-Fehler werden als
|
* führen zu einem leeren {@link Optional}. Andere unerwartete Laufzeitfehler
|
||||||
|
* propagieren zum Aufrufer. Erwartete Lookup-Fehler werden als
|
||||||
* {@code PersistenceLookupTechnicalFailure} im Rückgabewert kodiert und führen
|
* {@code PersistenceLookupTechnicalFailure} im Rückgabewert kodiert und führen
|
||||||
* zu einem leeren {@link Optional}.
|
* ebenfalls zu einem leeren {@link Optional}.
|
||||||
*/
|
*/
|
||||||
public class DefaultResolveHistoricalDocumentContextUseCase
|
public class DefaultResolveHistoricalDocumentContextUseCase
|
||||||
implements ResolveHistoricalDocumentContextUseCase {
|
implements ResolveHistoricalDocumentContextUseCase {
|
||||||
@@ -84,10 +86,10 @@ public class DefaultResolveHistoricalDocumentContextUseCase
|
|||||||
failure.record().lastFailureInstant()));
|
failure.record().lastFailureInstant()));
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
} catch (RuntimeException e) {
|
} catch (DocumentPersistenceException e) {
|
||||||
logger.warn("Unerwarteter Fehler beim Lesen des Dokument-Stammsatzes für Fingerprint {}: {}",
|
logger.warn("Persistenzfehler beim Lesen des Dokument-Stammsatzes für Fingerprint {}: {}",
|
||||||
fingerprint, e.getMessage(), e);
|
fingerprint, e.getMessage(), e);
|
||||||
throw e;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -7,6 +7,7 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.in.ResolveHistoricalFileNameUseCase;
|
import de.gecheckt.pdf.umbenenner.application.port.in.ResolveHistoricalFileNameUseCase;
|
||||||
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentPersistenceException;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordLookupResult;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordLookupResult;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentRecordRepository;
|
||||||
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentTerminalSuccess;
|
import de.gecheckt.pdf.umbenenner.application.port.out.DocumentTerminalSuccess;
|
||||||
@@ -21,10 +22,11 @@ import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;
|
|||||||
* <p>
|
* <p>
|
||||||
* Für alle anderen terminalen Zustände oder wenn kein Stammsatz vorhanden ist,
|
* Für alle anderen terminalen Zustände oder wenn kein Stammsatz vorhanden ist,
|
||||||
* wird ein leeres {@link Optional} zurückgegeben.
|
* wird ein leeres {@link Optional} zurückgegeben.
|
||||||
* Unerwartete {@link RuntimeException}s aus dem Repository werden geloggt (WARN) und
|
* {@link DocumentPersistenceException}s aus dem Repository werden geloggt (WARN) und
|
||||||
* weiterpropagiert. Erwartete Lookup-Fehler werden als
|
* führen zu einem leeren {@link Optional}. Andere unerwartete Laufzeitfehler
|
||||||
|
* propagieren zum Aufrufer. Erwartete Lookup-Fehler werden als
|
||||||
* {@code PersistenceLookupTechnicalFailure} im Rückgabewert kodiert und führen
|
* {@code PersistenceLookupTechnicalFailure} im Rückgabewert kodiert und führen
|
||||||
* zu einem leeren {@link Optional}.
|
* ebenfalls zu einem leeren {@link Optional}.
|
||||||
*/
|
*/
|
||||||
public class DefaultResolveHistoricalFileNameUseCase implements ResolveHistoricalFileNameUseCase {
|
public class DefaultResolveHistoricalFileNameUseCase implements ResolveHistoricalFileNameUseCase {
|
||||||
|
|
||||||
@@ -69,10 +71,10 @@ public class DefaultResolveHistoricalFileNameUseCase implements ResolveHistorica
|
|||||||
return Optional.ofNullable(success.record().lastTargetFileName());
|
return Optional.ofNullable(success.record().lastTargetFileName());
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
} catch (RuntimeException e) {
|
} catch (DocumentPersistenceException e) {
|
||||||
logger.warn("Unerwarteter Fehler beim Lesen des historischen Dateinamens für Fingerprint {}: {}",
|
logger.warn("Persistenzfehler beim Lesen des historischen Dateinamens für Fingerprint {}: {}",
|
||||||
fingerprint, e.getMessage(), e);
|
fingerprint, e.getMessage(), e);
|
||||||
throw e;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user