Alex Rivera | Logout

Sending events at the end of a transaction

Asked 2011-08-12T11:19:31.447
12

I have an interface for a Service object that looks something like the following (simplified for brevity):

public interface ItemService {

  public Item getItemById(String itemId, int version);

  public void create(Item item, User user);

  public void update(Item item, User user);

  public void delete(Item item, User user);

}

ItemService a single implementation, and is wired up as a Spring bean. It gets used by the UI portion of our project, and by the code that handles Ajax requests, to create and modify Item objects in our data store.

Under the hood each method sends out a series of Events when it gets called. The Events are received by other modules to do things like keep Lucene indexes up to date, or to send messages to administrators to let them know something has changed. Each method call constitutes a single transaction in Spring (using org.springframework.orm.hibernate3.HibernateTransactionManager and org.springframework.transaction.interceptor.TransactionProxyFactoryBean).

Recently there has been a need to compose a number of method calls together in a single transaction. Sometimes with more than one Service. For example, we might want to do something like:

*Begin transaction*
Get Items created by User Bill using ItemService
 for each Item in Items 
   Update field on Item
   Link Item to User Bill with LinkService 
   Update Item using ItemService
*Finish transaction* 

We've done this by creating another Service which allows you to compose calls from Services in a single method in the parent service. Lets call it ComposingService. ComposingService, as with all the others, is also managed by Spring, and as transactions are reentrant, this should all work..

However, there is a problem: if any of those operations within the transaction fail, causing the transaction to

Edit
Report

1 Answer

1

In contrast to Wouter Coekaerts I understand that you are asking for an way to send notifications that will be only submitted to the reciver if the transaction in which they are created was succesfull. -- So you are looking for something that is similar to the transactional CDI-Event mechanism.

My idea to solve it is this way:

  • send the events and "store" them in a list in your event handling mechanism, but do not forward the events to the recivers. (I guess that is easy to implement)
  • forward the events from the list to the recviers if the transaction was sucessfull
  • delete the events from the list if the transaction has a roll-backed

To forward or delete the events I would first have a lookt at the spring transaction mechanism. If there is no way to extend it, you could write an AOP aspect that forward the events if a method annotated with @Transactional was leaving wihtout an (Runtime)Exception. But if the @Transactional annotated Method was leaving with an (Runtime)Exception then delete the events from the list.

answered 2011-08-12T11:41:46.080

Your Answer