Hi Samir,

I finally got around to follow up on this interesting topic. There's in 
fact already a feature request for this in the Spring Framework:
https://jira.spring.io/browse/SPR-13724

I have cross-referenced this discussion and your use-case. Let's see what 
happens.

Cheers,
Lukas

Am Samstag, 28. Mai 2016 10:23:33 UTC+2 schrieb Lukas Eder:
>
> Hi Samir,
>
> Thank you very much for elaborating. I see, it's tangent, but it's still 
> interesting to remember the bigger picture when designing API. Your use 
> case could be covered if you were using jOOQ's transaction API, which 
> allows you to register a TransactionProvider:
> http://www.jooq.org/javadoc/latest/org/jooq/TransactionProvider.html
>
> Your provider can be bound to any transaction implementation, including 
> Spring TX, for instance.
>
> With JTA, you'd probably be looking up a UserTransaction from JNDI, and 
> that might happen in a very specific transaction layer, where you could 
> inject your logic. I've done that for a previous employer, where we 
> initialised the PL/SQL session context with global variables at the 
> beginning of each transaction.
>
> Another option might perhaps be to intercept this on a connection pool 
> level? After all, a transaction usually begins right when the connection is 
> acquired from the pool.
>
> Interesting to see that Spring's TransactionalEventListener / 
> TransactionPhase don't support any "BEFORE BEGIN" or "AFTER BEGIN" phases. 
> You might be able to work around this by implementing your 
> own PlatformTransactionManager, delegating to your existing one. You'd be 
> injecting your logic right after 
> the PlatformTransactionManager.getTransaction(TransactionDefinition) method.
>
> Hope this helps,
> Lukas
>
> 2016-05-27 23:12 GMT+02:00 Samir Faci <[email protected]>:
>
>> This is sort of a tangent so i'll try to be concise.  
>>
>> My use case was that we need to insert something and interject in the 
>> middle of a transaction.
>>
>> ie.  
>>
>> begin transaction;
>> *// insert into audit_table(app_id, transaction_id);*
>> // insert  + update a bunch of different tables
>> // commit transaction;
>>
>> The part in the middle is really difficult to perform with the current 
>> spring wiring that we're using.  They have a pre-commit and a post-commit 
>> but in the pre-commit the transaction ID is invalid, in the post-commit we 
>> can do a valid insert but it's too late
>> since the trigger we have on the table would have already executed.  So 
>> we need something that would be executed right after the transaction has 
>> started.
>>
>> We played around with spring 4.x, TransactionEvents etc and all of them 
>> are lacking unless you completely hijack the transaction and handle it 
>> manually.
>>
>> The snippet you posted really caught my eye cause it seems to directly be 
>> relevant to my use case.  
>>
>> --
>> Samir Faci
>>
>>
>>
>>
>>
>> On Fri, May 27, 2016 at 12:00 AM, Lukas Eder <[email protected]> 
>> wrote:
>>
>>> Thanks, Samir
>>>
>>> 2016-05-26 23:35 GMT+02:00 Samir Faci <[email protected]>:
>>>
>>>> I also have a use case where I need to inject some additional SQL to be 
>>>> executed within the same transaction.  
>>>>
>>>
>>> Would you mind elaborating your use-case a little bit?
>>>  
>>>
>>>> the code snippet you describe would sound ideal for us.
>>>>
>>>>
>>>> ctx.beginTransactionAsync()
>>>>    .thenApply(... -> ...)
>>>>    .thenApply(... -> ...)
>>>>    .thenApply(... -> commit());
>>>>
>>>>
>>> So far, this was just a very high level sketch. Let's assume we'd be 
>>> going this way. There would be two new alternative transaction APIs: A 
>>> blocking one and a non-blocking one. The blocking one might look just like 
>>> JDBC or JTA:
>>>
>>> Transaction transaction = ctx.beginTransaction();
>>> ctx.insert()...
>>> ctx.update()...
>>>
>>> Savepoint savepoint = transaction.savepoint();
>>>
>>> ctx.delete()...
>>> transaction.commit();
>>>
>>>
>>> The non-blocking one would need to maintain the transaction state 
>>> throughout the .thenApply() call chain, exposing it in case someone 
>>> wants to nest stuff (using savepoints) or commit/rollback early. 
>>>
>>> The difficulty of this is that CompletionStage is not designed for this 
>>> use-case. It is designed for passing only computation results to the next 
>>> computation, not (transaction) contexts. This means that the context needs 
>>> to stay external or implicit, which also violates the CompletionStage 
>>> design.
>>>
>>> One option would be to subtype the JDK's CompletionStage and make that a 
>>> TransactionalCompletionStage. So, more specifically than what I've stated 
>>> earlier:
>>>
>>> ctx.beginTransactionAsync()
>>>    .thenApply(transaction -> transaction.ctx().insert())
>>>    .thenApply(transaction -> transaction.ctx().update())
>>>    .thenApply(transaction -> transaction.savepoint())
>>>    .thenApply(transaction -> transaction.ctx().delete())
>>>    .thenApply(transaction -> commit());
>>>
>>>
>>> Where "transaction" would be that TransactionalCompletionStage<T>, where 
>>> <T> is the outcome of the previous computation (Integer in case of 
>>> insert/update/delete, Result in case of fetch, Void in case of savepoint).
>>>
>>> I'm a bit wary of implementing that, though. There hasn't been a lot of 
>>> literature around, documenting such things (as with subtyping the 
>>> Collections API). 
>>> I'm very open to hear your thoughts on this matter.
>>>
>>> Best
>>> Lukas
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "jOOQ User Group" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>>
>> -- 
>> Thank you
>> Samir Faci
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "jOOQ User Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "jOOQ 
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to