-
Notifications
You must be signed in to change notification settings - Fork 7
Dropwizard unit of work #50
base: master
Are you sure you want to change the base?
Dropwizard unit of work #50
Conversation
@@ -78,6 +78,7 @@ | |||
<sonar.host.url>https://sonarcloud.io</sonar.host.url> | |||
|
|||
<jdbi.version>2.78</jdbi.version> | |||
<org.reflections.version>0.10.2</org.reflections.version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need reflections
for helping users take in a list of packages and automagically return all "Dao" specific classes annotated with SqlUpdate
/ SqlQuery
/ SqlCall
/ SqlBatch` etc.
import java.util.stream.Collectors; | ||
|
||
@SuppressWarnings({"UnstableApiUsage", "rawtypes", "unchecked"}) | ||
public class JdbiUnitOfWorkProvider { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only point of access for the users unless they want to do something low level for which a getter is exposed getHandleManager()
* dao requests between multiple threads. | ||
* Note: Not suitable when you can not set the name format for the newly spawned threads. | ||
**/ | ||
class LinkedRequestScopedJdbiHandleManager implements JdbiHandleManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users would use this as follows
JdbiUnitOfWorkProvider provider = JdbiUnitOfWorkProvider.withLinked(dbi);
...
RequestEvent.Type type = event.getType(); | ||
log.debug("Handling GET Request Event {} {}", type, Thread.currentThread().getId()); | ||
|
||
if (type == RequestEvent.Type.FINISHED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialisation would be done by dao access methods
. Every dao access goes through a handle manager to get the handle.
We make sure to close the handle at the end of the request lifecycle.
throw new IllegalArgumentException(String.format("Class [%s] has no method annotated with a Jdbi SQL Object", daoClass.getSimpleName())); | ||
} | ||
|
||
log.info("Binding class [{}] with proxy handler [{}] ", daoClass.getSimpleName(), handleManager.getClass().getSimpleName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the app starts and the users have configured a provider, it looks like
INFO [2022-01-15 19:21:16,787] io.dropwizard.server.DefaultServerFactory: Registering jersey handler with root path prefix: /
INFO [2022-01-15 19:21:16,790] io.dropwizard.server.DefaultServerFactory: Registering admin handler with root path prefix: /
...
INFO [2022-01-15 19:21:16,848] com.github.isopropylcyanide.jdbiunitofwork.core.JdbiUnitOfWorkProvider: Binding class [AppDao] with proxy handler [LinkedRequestScopedJdbiHandleManager]
INFO [2022-01-15 19:21:16,855] com.github.isopropylcyanide.jdbiunitofwork.core.JdbiUnitOfWorkProvider: Binding class [CountingDao] with proxy handler [LinkedRequestScopedJdbiHandleManager]
...
INFO [2022-01-15 19:21:16,859] io.dropwizard.server.ServerFactory: Starting SampleApplication
if (excludedPaths.stream().anyMatch(path::contains)) { | ||
return null; | ||
} | ||
if (event.getContainerRequest().getMethod().equals(HttpMethod.GET)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not every request would like to get itself attached to GET/POST listeners, which is why consumers have a way to exclude
certain paths from this listener.
|
||
private DBI dbi; | ||
|
||
private LinkedRequestScopedJdbiHandleManager manager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is all about testing whether multiple threads can share a common thread handle safely
@joschi Mind taking a stab at this? Would appreciate it. Thanks |
@JdbiUnitOfWork - Unit of Work Support
Further to our discussion on #14 with @joschi , adding an initial implementation. from the original source https://github.com/isopropylcyanide/dropwizard-jdbi-unitofwork. I've blogged about it as well. Tweet
This Provides a
Unit of Work
annotation for a Jdbi backed Dropwizard service for wrapping resource methods in a transaction contextDropwizard
provides a very slick@UnitOfWork
annotation that wraps a transaction context around resource methods annotated with this annotation. This is very useful for wrapping multiple calls in a single database transaction all of which will succeed or roll back atomically.However this support is only available for
Hibernate
. This module provides support for aJdbi
backendFeatures
transactional
across multiple datasources when called from a request threadtransactional
across multiple datasources acrossmultiple threads
excluding
selectively, certain set of URI's from transaction contexts, such asELB
,Health Checks
etcHttp GET
methods are excluded from transaction by default.Http POST
methods are wrapped around in a transaction only when annotated with@JdbiUnitOfWork
Usage
dropwizard-jdbi
Motivation
Jdbi-2
and eventually toJDBI-3
if this PR gets merged. I feel this would be a valuable feature add for folks looking to get aUnitOfWork
working for JDBIAll that's required is to
dropwizard-jdbi
dependency (no op for existing consumers)JdbiUnitOfWorkProvider
@JdbiUnitOfWork
Disclaimer
I'm not well versed with the whole versioning thing going on with Dropwizard (1.3 -> 2.0). I'd need your help in getting this reviewed and possibly merged. Thank you.