Make PersistenceManager Less Error Prone (#83)

Reviewed-on: https://git.kske.dev/zdm/envoy/pulls/83
Reviewed-by: kske <kai@kske.dev>
Reviewed-by: DieGurke <maxi@kske.dev>
This commit is contained in:
Leon Hofmeister 2020-10-07 22:13:42 +02:00
parent 6f9982bbc3
commit f2eb89d469
Signed by: Käfer & Engelbart Git
GPG Key ID: 70F2F9206EDC1FCE
1 changed files with 22 additions and 41 deletions

View File

@ -28,15 +28,13 @@ public final class PersistenceManager {
* @since Envoy Server Standalone v0.1-alpha * @since Envoy Server Standalone v0.1-alpha
*/ */
private PersistenceManager() { private PersistenceManager() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> transaction(() -> {
transaction.begin();
ConnectionManager.getInstance() ConnectionManager.getInstance()
.getOnlineUsers() .getOnlineUsers()
.stream() .stream()
.map(this::getUserByID) .map(this::getUserByID)
.forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); }); .forEach(user -> { user.setStatus(UserStatus.OFFLINE); user.setLastSeen(Instant.now()); entityManager.merge(user); });
transaction.commit(); })));
}));
} }
/** /**
@ -239,10 +237,7 @@ public final class PersistenceManager {
c2.getContacts().add(c1); c2.getContacts().add(c1);
// Synchronize changes with the database // Synchronize changes with the database
transaction.begin(); transaction(() -> { entityManager.merge(c1); entityManager.merge(c2); });
entityManager.merge(c1);
entityManager.merge(c2);
transaction.commit();
} }
/** /**
@ -254,47 +249,33 @@ public final class PersistenceManager {
return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList(); return entityManager.createNamedQuery(User.findContacts).setParameter("user", user).getResultList();
} }
private void persist(Object obj) { private void persist(Object obj) { transaction(() -> entityManager.persist(obj)); }
private void merge(Object obj) { transaction(() -> entityManager.merge(obj)); }
private void remove(Object obj) { transaction(() -> entityManager.remove(obj)); }
/**
* Performs a transaction with the given Runnable, that should somewhere call
* {@link EntityManager}.
*
* @param entityManagerRelatedAction the action that changes something in the
* database
* @since Envoy Server v0.3-beta
*/
private void transaction(Runnable entityManagerRelatedAction) {
try { try {
transaction.begin(); transaction.begin();
entityManager.persist(obj); entityManagerRelatedAction.run();
transaction.commit(); transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed // Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) { } catch (final IllegalStateException e) {
if (transaction.isActive()) { if (transaction.isActive()) {
transaction.rollback(); transaction.rollback();
persist(obj); transaction.begin();
} entityManagerRelatedAction.run();
} transaction.commit();
}
private void merge(Object obj) {
try {
transaction.begin();
entityManager.merge(obj);
transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) {
if (transaction.isActive()) {
transaction.rollback();
merge(obj);
}
}
}
private void remove(Object obj) {
try {
transaction.begin();
entityManager.remove(obj);
transaction.commit();
// Last transaction threw an error resulting in the transaction not being closed
} catch (final IllegalStateException e) {
if (transaction.isActive()) {
transaction.rollback();
remove(obj);
} }
} }
} }