Skip to content

Commit efc7ebd

Browse files
authored
Moved transaction handling into Handle instead of @transactional (#4966)
* Moved transaction handling into Handle instead of @transactional * Debug PG database errors * Use SQL upsert when adding or creating branches * Fixed some sql statements
1 parent a2413e4 commit efc7ebd

10 files changed

+406
-379
lines changed

app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractHandleFactory.java

+44-28
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@
22

33
import io.agroal.api.AgroalDataSource;
44
import io.apicurio.registry.storage.error.RegistryStorageException;
5-
import io.apicurio.registry.storage.impl.sql.jdb.Handle;
65
import io.apicurio.registry.storage.impl.sql.jdb.HandleAction;
76
import io.apicurio.registry.storage.impl.sql.jdb.HandleCallback;
87
import io.apicurio.registry.storage.impl.sql.jdb.HandleImpl;
98
import org.slf4j.Logger;
109

11-
import java.io.IOException;
1210
import java.sql.SQLException;
1311
import java.util.HashMap;
1412
import java.util.Map;
@@ -32,35 +30,56 @@ protected void initialize(AgroalDataSource dataSource, String dataSourceId, Logg
3230

3331
@Override
3432
public <R, X extends Exception> R withHandle(HandleCallback<R, X> callback) throws X {
35-
/*
36-
* Handles are cached and reused if calls to this method are nested. Make sure that all nested uses of
37-
* a handle are either within a transaction context, or without one. Starting a transaction with a
38-
* nested handle will cause an exception.
39-
*/
33+
LocalState state = state();
4034
try {
41-
if (get().handle == null) {
42-
get().handle = new HandleImpl(dataSource.getConnection());
35+
// Create a new handle, or throw if one already exists (only one handle allowed at a time)
36+
if (state.handle == null) {
37+
state.handle = new HandleImpl(dataSource.getConnection());
4338
} else {
44-
get().level++;
39+
throw new RegistryStorageException("Attempt to acquire a nested DB Handle.");
4540
}
46-
return callback.withHandle(get().handle);
41+
42+
// Invoke the callback with the handle. This will either return a value (success)
43+
// or throw some sort of exception.
44+
return callback.withHandle(state.handle);
4745
} catch (SQLException e) {
46+
// If a SQL exception is thrown, set the handle to rollback.
47+
state.handle.setRollback(true);
48+
// Wrap the SQL exception.
4849
throw new RegistryStorageException(e);
50+
} catch (Exception e) {
51+
// If any other exception is thrown, also set the handle to rollback.
52+
if (state.handle != null) {
53+
state.handle.setRollback(true);
54+
}
55+
throw e;
4956
} finally {
50-
if (get().level > 0) {
51-
get().level--;
52-
} else {
53-
try {
54-
LocalState partialState = get();
55-
if (partialState.handle != null) {
56-
partialState.handle.close();
57+
// Commit or rollback the transaction
58+
try {
59+
if (state.handle != null) {
60+
if (state.handle.isRollback()) {
61+
log.trace("Rollback: {} #{}", state.handle.getConnection(),
62+
state.handle.getConnection().hashCode());
63+
state.handle.getConnection().rollback();
64+
} else {
65+
log.trace("Commit: {} #{}", state.handle.getConnection(),
66+
state.handle.getConnection().hashCode());
67+
state().handle.getConnection().commit();
5768
}
58-
} catch (IOException ex) {
59-
// Nothing we can do
60-
log.error("Could not close a database handle", ex);
61-
} finally {
62-
local.get().remove(dataSourceId);
6369
}
70+
} catch (Exception e) {
71+
log.error("Could not release database connection/transaction", e);
72+
}
73+
74+
// Close the connection
75+
try {
76+
if (state.handle != null) {
77+
state.handle.close();
78+
state.handle = null;
79+
}
80+
} catch (Exception ex) {
81+
// Nothing we can do
82+
log.error("Could not close a database connection.", ex);
6483
}
6584
}
6685
}
@@ -84,14 +103,11 @@ public <X extends Exception> void withHandleNoException(HandleAction<X> action)
84103
});
85104
}
86105

87-
private LocalState get() {
106+
private LocalState state() {
88107
return local.get().computeIfAbsent(dataSourceId, k -> new LocalState());
89108
}
90109

91110
private static class LocalState {
92-
93-
Handle handle;
94-
95-
int level;
111+
HandleImpl handle;
96112
}
97113
}

0 commit comments

Comments
 (0)