There are other approaches that do not require integration of Kafka or Rest
into an XA transaction.
One, that I do not particularly like, is to use Outbox pattern(Debezium) (I
do not like it because it requires another process, that is responsible to
send the events, even in sunny day scenarios, and with all the events we
have that going to affect the sunny day scenario performance, which is a
huge problem in my opinion)
Or, the one that I would use, is to use a Debezium like approach, but
without the external process performing the Kafka or Rest call.
The approach will be, for every "transaction".
Sunny day. >  write a log of the operation in the primary BD, the commit,
then write the data in the DB and update the log entry to db written, then
commit in the DB, then t send the event (Rest or Kafka or whatever), once
it is confirmed (thats trivial in Kafka and in REST) that the event has
been dispatches, delete the log in the primary DB.
Rainy day 1 -> the db is down and failed in the operation log commit, we
throw an exception, nothing is written and the user cries, but no
inconsistency.
Rainy daty 2 -> the db goes down between the log commit and the write data
commit. Then it appears the "log checker" (which is a thread or a process
responsible to deal with rainy day situations), it eventually reads the log
and see something goes wrong, but not data has been written in db, so it
deletes the log entry (It is pretty unlikely this escenario ever happen,
but it is anyway covered)
Rainy data 3 -> (the most likely failure when not using kafka) the write
data commit succeeded but when publishing the event something goes wrong
(since Kafka is a db itself, this is not very likely, with http it will
happen more frequently), then the log will remain is state "written to db"
and when the "log checker" is activated, it will realize it has to try to
send the event that was not send. Once it successes on sending the event
(order is relevant here), it will delete the log entry.

What can be wrong? Many things as in any approach ;), the most delicate
escenario is when the log checker fails to delete the log entry after a
successful event sending. This will lead to the same event being published
twice, which is something that also happens with Outbox pattern. The other
problem is to define what to write in the log entry and how to run the log
checker. The main advantage is that sunny day scenario does not require (as
happend with debezium) the external process to send the event from the db
logs. The main disadvantage is that there is an extra write to the db (and
an extra delete).
Why bother to implement this approach if we can integrate REST/Kaka into
Quarkus/Springboot XA? I think this approach captures better the most
likely failing point (sending the event) and does not rollback the whole
operation because the event was not propagated, while at the same time
guarantees it will be eventually propagated.
Why consider this option if we have Outbox? Because on sunny day scenarios
events will be sent as soon as they are available, while in Outbox there is
always a delay (not to mention that the publisher process can go down too,
which adds another piece in the set of possible things that can go wrong).
The overall assumption is that error happens, but does not happen all the
time and we should not substantially decrease performance of sunny days to
cover rainy days if we can.




On Fri, Aug 2, 2024 at 10:09 AM Pere Fernandez (apache) <pefer...@apache.org>
wrote:

>  +1 to transactions!
>
> On Fri, 2 Aug 2024 at 08:39, Enrique Gonzalez Martinez <
> egonza...@apache.org>
> wrote:
>
> > * Transactions*
> > This document describes how to support transactions in the domain of
> > workflow engine and subsystems.
> >
> > The use cases for transactions in workflows is to enable consistency
> > during workflow executions.
> >
> > * Constraints *
> >
> > The constraints for this are related to different types of transaction
> > problems:
> >
> > Workflow transaction execution should be in one single transaction
> > (until idle elements are reached or there are no more elements to
> > process)
> >
> > Process state should be consistent in storage in one single
> > transaction. In the case of database multiple tables should be written
> > in an atomic transaction
> >
> > Reactive code should be removed as it does not behave properly with
> > transactions.
> >
> > Transactions Policy among workflow runtime and subsystems should be
> > consistent in terms of configuration (no subcomponent should start a
> > transaction if there is already one on the go, but they should mandate
> > to be in a transaction)
> >
> > Error handling should still produce an event that can be stored.
> >
> > Subsystems execution should be included during transactions
> >
> > Async execution will spawn its own transaction.
> >
> > * Architecture *
> >
> > The architecture of the solution impacts some areas:
> >
> > Components with reactive that are involved in transaction refactor. So
> > far, the only subsystem using reactive code job service.
> >
> > Process Code generation should change in order to reflect the
> > transactions of the workflow engine
> >
> > Error handling should be modified in a way the error is captured
> > outside the transaction and handled in a different one to avoid event
> > loss.
> >
> > Exchange information among runtime and subsystems should be in a way
> > that those elements are involved in a transaction or they can be
> > rolled back. At the moment the communication is being done with a rest
> > call that is not part of the transaction and cannot be rolled back.
> >
> > Events produced within the transaction should be part of the
> > transaction as well to avoid phantom events (events producing during
> > workflow execution that are sent at the end of the unit of work)
> >
> > * Risk Assessment *
> >
> > The risks identified for this work are the following:
> >
> > Error handling can be problematic depending where we set the
> > boundaries of the transaction. There are two different approaches:
> >
> > Boilerplate code for each task to start / commit / rollback the
> > transaction and deail with error in the rest call tier itself
> >
> > Use the runtime environment to install error handling for doing the
> > operation.
> >
> > Exchange information among systems in a non-transactional way. There
> > are a couple of approaches
> >
> > Install every time a transaction sync listener whenever the rest call
> > is made against the subsystem and doing a compensation when it fails
> >
> > Wrap the rest call in a XAResource that can be enlisted in the
> transaction.
> >
> > The use of Kafka clients for stream that does not belong to the
> > transactions
> >
> > Wrap with XAResource (Kafka client support transactions, but does not
> > offer XAresource)
> >
> > Install a transaction sync for each transaction.
> >
> > Performance impact with transactions.
> >
> > Different transaction methods in quarkus and spring boot
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscr...@kie.apache.org
> > For additional commands, e-mail: dev-h...@kie.apache.org
>

Reply via email to