3.3 PlaceOrder TransactionScope

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
9 years ago
Hi!

Why TransactionScope is commented in nop source?


//save order in data storage
//uncomment this line to support transactions
//using (var scope = new System.Transactions.TransactionScope())


Is it very useful, isnt it?
9 years ago
anyone?
9 years ago
Staff guys, any comment about it?

Thanks!
9 years ago
It was commented because transactions are not supported by SQL Compact
9 years ago
So, is highly recommended I uncomment it, right?
9 years ago
Sure, you do it. But it wasn't tested for a long time. Full support for unit of work pattern is not implanted yet.
9 years ago
There are 2 big problems, because of this:


                        scope.Complete();

                        //raise event      
                        _eventPublisher.Publish(new OrderPlacedEvent(order));

                        if (order.PaymentStatus == PaymentStatus.Paid)
                        {
                            ProcessOrderPaid(order);
                        }


1- call OrderPlacedEvent and ProcessOrderPaid after transation completes. If some plugin tries to add notes or others DB transaction, they will get an "the underlying provider failed on open" because the transaction is closed.

2- If you call them before transaction completes and some overrode method has untreated errors, all you order is gone and the problem is bigger.

So, we need to make some error handling to prevent 3rd party code breaks the placeorder transaction.

What do you think?

Ivan.
8 years ago
ivanslater wrote:

1- call OrderPlacedEvent and ProcessOrderPaid after transation completes. If some plugin tries to add notes or others DB transaction, they will get an "the underlying provider failed on open" because the transaction is closed.


--> The events should be called BEFORE the transaction is committed. Event handlers can then do changes that will be committed with the transaction. This way either the whole thing works or it doesn't. BUT, the operations in the event handlers should be only critical operations that need to be transactional with the core operation.
Only critical operations should be done in the transaction to minimize the chances of failure.

ivanslater wrote:

2- If you call them before transaction completes and some overrode method has untreated errors, all you order is gone and the problem is bigger.


--> The problem is only bigger if the operation that failed could be eventually consistent with the main operation, otherwise committing the order swallowing the error would be even worse.
The solution here is to separate transactional operations from eventually consistent operations. The way of doing it is:
1.- Execute all critical modifications in one local transaction (nop db)
2.- Within the local transaction, also store the event on a table (this is done in the transaction, so if the operation succeeds there'll be an event in the table, if the operation fails, the event won't be there)
3.- Later, using a task or other mechanism, check the events table to see if there are unprocessed events, process them and mark them as processed.

The main weakness here is that if there is a crash after processing the events and marking them as processed, it can happen that some operations are executed twice (things can be done to prevent this in most cases)
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.