I am trying to understand how I can introduce transactions across services in Spring.
I have organization class and every organization will have a associated superadmin. I am creating an organization and then creating super user for it. But I would like to execute these in a transaction, i.e if super admin creation fails, then organization row which got inserted by createOrganization() method should be rolled back. I am using JOOQ to handle DB operations.
How can I achieve transactions across services(organizationService and userService) ?
addSuperAdmin(Organization organizationObject, SuperUser superUserObject)
{
String orgId = organizationService.createOrganization(organizationObject);
superUserObject.orgId = orgId;
userService.AddSuperAdminDetailsToDB(superUserObject);
}
You seem to want to mix Spring's dependency injection and configuration of (transactional?) data sources with jOOQ's transaction API. That is a path you will probably regret many times.
jOOQ's transaction API works like this:
// Some pre-configured DSLContext with a Configuration
ctx1.transaction(config2 -> {
// A derived, transactional DSLContext with a derived Configuration
config2.dsl().insertInto(...).execute();
});
The idea is that you're passing around derived Configuration
objects which contain their transactional state. The original Configuration
object (ctx1
in my example) is unaware of any transactions that have been started.
This is quite different from how Spring models thread-bound transactions that are updated based on whether you're entering a @Transactional
annotated method, which updates the global transaction state for your thread context.
Since you're probably injecting a jOOQ DSLContext
containing a Configuration
and a DataSource
to all your services, you must remove that again, and pass around the transactional DSLContext
that you prefer to use instead. It's not impossible, but it's just not idiomatic in the "Spring world". Every time you forget this, you'll pay the price by having a jOOQ transaction, a separate Spring transaction, and the two things being unaware of each other.
Why not just use Spring's @Transactional
annotations everywhere, instead?