简体   繁体   中英

Transactions and events together

This is more of a conceptual question. I'm writing a transactional based server-client application with the use of ORM.. Basically it means every layer knows how to work with transaction blocks for example here is a web service layer implementation:

public HandleTransaction<TReturn>(Action<TReturn>)
{
    bool opendByMe = false;

    // Some static transaction manager
    var transactionMgr = GetTransactionManager();

    try
    {
       // If not opened before me
       if(!transactionMgr.IsActive)
       {
           transactionMgr.BeginTransaction();
           opendByMe = true;
       }    

       // Run the action
       var returnValue = action();

       // If we opened the transaction then we should close it
       if(opendByMe)
       {
           transactionMgr.Commit();
       }

       return returnValue;
    }

    catch
    {
       if(opendByMe)
       {
          if(transactionMgr.IsActive)
          {
              // Rollback only if i opened the transaction
              transactionMgr.Rollback();  
          }  
       }

       // Else, bubble exception
       throw;
    }
}

public void ServiceWork1()  
{  
    // Subscribe to person event
    PersonBL.PersonChanged += HandlePersonChanged(Person pers);

    HandleTransaction(() =>  
          {  
                // BL actions are made in a bulk.. If one of them fails the transaction  
                // should be rolled back  
                PersonBL.CreatePerson("Jeff");  
                PersonBL.CreatePerson("John");  
                PersonBL.CreatePerson("Peter");  
              };)  
    }   

public void HandlePersonChanged(Person pers)
{
    // Notify some one
}

This works great but now I want to add some event to my application ie PersonCreatedEvent.. The problem is integrating the event bubbling with the transactions.. In the example above lets say the PersonBL.CreatePerson() method fires a "PersonChanged" event to the service layer.. Then the service layer handles this event and fires an event to the client.. But I don't want to fire these events before I know for sure that the transaction was committed. The BL layer doesn't know my business transaction logic so it fires the event in the CreatePerson method..
Is there any design solution for stacking/handling the events i subscribed to only after I completed the transaction?

To simplify my question: I want to execute HandlePersonChanged in a bulk after commit only..

I want to execute HandlePersonChanged in a bulk after commit only.

As per theory, Events should be fired since data is changed.

Second Solution:

you can implement some queue structure. save events until completion transaction. and over transaction completion event, process the queue.

I've ended up building an Action Queue which stores all the events fired during the transaction from different components.
Then, upon committing a transaction in the ORM (I have an OnCommit event) the queue fires all it's stored events one by one.. Of course, if the OnRollback event is fired, the Action queue is cleared and restarted.
This "Action queue" is in the Infrastructure layer which is known across all layers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM