Hi Zhang Lei,
What I'm trying to say is to provide a way for user to send
TxEndedEvent, TxAbortedEvent, TxCompensatedEvent, SagaEndedEvent ...
explicitly on Omega side.
Because current implementation doesn't support following situation(async):
@Compensable(compensationMethod="rollbackFoo")
public void foo() {
new Thread(() -> /* local tx goes here */).start();
// TxEndedEvent sent when returns, it's too early
}
public void rollbackFoo() {
new Thread(() -> /* compensation goes here*/).start();
// TxCompensatedEvent sent when returns, it's too early
}
@SagaStart
public void bar() {
new Thread(() -> /* call other service goes here */).start();
// SagaEndedEvent sent when returns, it's too early
}
I suggest providing a helper class, called omega or something else,
user can use it to send TxEndedEvent, TxAbortedEvent,
TxCompensatedEvent, SagaEndedEvent, etc. So the code goes like this:
@Compensable(async=true, compensationMethod="rollbackFoo",
compensationAsync=true)
public void foo() {
TransactionContext txContext = omegaContext.getTransactionContext();
new Thread(() -> {
try {
/* local tx goes here */
omega.txEnded(txContext);
} catch(Exception e) {
omega.txAborted(txContext);
}
}).start();
}
public void rollbackFoo() {
TransactionContext txContext = omegaContext.getTransactionContext();
new Thread(() -> {
/*compensation goes here*/
omega.txCompensated()
}).start();
}
@SagaStart(async=true)
public void bar() {
TransactionContext txContext = omegaContext.getTransactionContext();
new Thread(() -> {
/* call other service goes here */
try {
omega.sagaEnded(txContext);
} catch (Exception e) {
omega.sagaAborted(txContext);
}
}).start();
}
Zhang Lei 于2019年7月25日周四 下午4:46写道:
Zhang Lei 于2019年7月25日周四 下午4:46写道:
>
> Hi, Daniel Qian
>
> Are you talking about the asynchronous problem with the @SagaStart and
> @Compensable methods on the Omega side? I think this is a typical long
> transaction scene.
>
> Alpha based on Actor model has implemented asynchronous processing of Omega
> and Alpha, The event sent to Alpha needs to ensure that all child
> transactions have been executed before sending SagaEndedEvent or
> SagaAbortedEvent.
>
> Lei Zhang
>
> > 在 2019年7月20日,下午9:49,Daniel Qian 写道:
> >
> > After look into SCB-163, SCB-1385 and SCB-1386 I have some thoughts on Saga
> > involved in async invocation.
> > Current implementation is basically based on sync invocation, there are
> > some assumption:
> >
> > 1. When @SagaStart method returns, the Saga finished.
> > 2. When @Compensable method returns/throws exception, the Local Tx
> > succeeds/failed.
> > 3. When compensationMethod returns, the Local Tx is compensated.
> >
> > Even if considering what SCB-100 provided:
> >
> > 1. Add @OmegaContextAware annotation enabling
> > java.util.concurrent.Executor inject OmegaConext into threads it
> > manages/spawns
> > 2. Make OmegaContext use InheritableThreadLocal field let child thread
> > inherit parent thread's Local Tx info
> >
> > There are still some limitations:
> >
> > 1. @OmegaContextAware is only viable if you use spring framework
> > 2. @OmegaContextAware and OmegaContext's InheritableThreadLocal field
> > assuming that the calling thread or initator thread has Local Tx info.
> >
> >
> > What if user code use producer-consumer pattern in which
> > InheritableThreadLocal can't work?
> > What if user code use a thread scheduling library which we cannot use
> > @OmegaContextAware,RxJava and Reactor, for example?
> > I think we could provide some low-level APIs that user code can manualy
> > starts/ends Saga and Local Tx, something like below:
> >
> > TxContext context = omega.startSaga();
> > TxContext subTxContext = omega.startTx(TxContext parentTxContext);
> > omega.endTx(TxContext);
> > omega.abortTx(TxContext);
> > omega.abortSaga(TxContext);
> > omega.endSaga(TxContext);
> >
> > TxContext is just a immutable dto like this:
> >
> > public class TxContext {
> > private final String globalTxId;
> > private final String localTxId;
> > }
> >
> > Above is a just a rough idea. So any thoughts?
> > --
> > Daniel Qian
> >
> > 博客:https://segmentfault.com/u/chanjarster
> > github:https://github.com/chanjarster
>
--
Daniel Qian
博客:https://segmentfault.com/u/chanjarster
github:https://github.com/chanjarster