Skip to content

A plugin for Spring Framework 3.2 for publishing events only after a successfull transaction

License

Notifications You must be signed in to change notification settings

diepet/spring-tx-eventpublisher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spring-tx-eventpublisher License: MIT

A Spring Framework 3.2 plugin for publishing events only after a successfull transaction.

This plugin could be useful in projects still using Spring 3.2, because adds to these projects a similar feature implemented by using the @TransactionalEventListener annotation available in Spring 4.

Requisites

Configuration

  • Configure a transaction manager as explained here, in order to dispatch transaction lifecycle events.
  • Configure a transaction context manager as explained here.
  • Import META-INF/eventpublisher-tx-spring-application-context.xml Spring configuration file.
  • Define a new Spring bean inheriting its configuration from transactionalEventPublisherAbstract abstract bean and injects the transaction context manager by setting the property transactionContextManager.

Example:

	<!-- TX Manager configuration by using spring-tx-lifecycle -->		
	<bean id="transactionManager" class="it.diepet.spring.tx.lifecycle.EventDispatcherJpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory"></property>
	</bean>
	
	<!--Creates a transaction context manager by using spring-tx-context -->
	<import resource="classpath:META-INF/context-tx-spring-application-context.xml"/>
	<bean id="transactionContextManager" parent="transactionContextManagerAbstract" />
	
	<!--import spring-tx-eventpublisher configuration: no any instance will be created in the Spring context-->
	<import resource="classpath:META-INF/eventpublisher-tx-spring-application-context.xml"/>
	
	<!-- Creates the transactional event publisher and injects the transaction context manager -->
	<bean id="transactionalEventPublisher" parent="transactionalEventPublisherAbstract">
		<!-- Required -->
		<property name="transactionContextManager" ref="transactionContextManager" />
	</bean> 

And that's it. The configuration for using the transactional event publisher is completed.

Usage

After configured a transactional event publisher, creates a custom event by extending the abstract class:

it.diepet.spring.tx.eventpublisher.event.TransactionalEvent

(note that it.diepet.spring.tx.eventpublisher.event.TransactionalEvent is a subclass of the Spring base event abstract class org.springframework.context.ApplicationEvent).

For example:

import it.diepet.spring.tx.eventpublisher.event.TransactionalEvent;

public class CustomTransactionalEvent extends TransactionalEvent {

	private String message;

	public CustomTransactionalEvent(String message) {
		super(message);
		this.message = message;
	}

	public String getMessage() {
		return message;
	}

}

Finally, injects the transactional event publisher in a class executing operations inside a transaction. All the events published will be really published only if the transaction completes successfully (commit succeeds).

For example:

import it.diepet.spring.tx.eventpublisher.TransactionalEventPublisher;

public class ProductServiceImpl implements ProductService {

	@Autowired
	private TransactionalEventPublisher transactionalEventPublisher;

	@Transactional
	public void createProduct(Product p) {
		
		// some db stuff
		
		// the event will be published automatically later, 
		// only if the transaction completes successfully
		transactionalEventPublisher.publishEvent(new CustomTransactionalEvent("Product created"));
		
		// some db stuff
	}

} 

Furthermore notes

The transactional event publisher:

it.diepet.spring.tx.eventpublisher.TransactionalEventPublisher

and the Spring classic event publisher:

org.springframework.context.ApplicationEventPublisher

are two different interfaces, but share the same method for publishing events:

void publishEvent(ApplicationEvent event);

So the transactional event publisher can be used for publishing any kind of Spring event class. But if the published event extend the org.springframework.context.ApplicationEvent class but not extend it.diepet.spring.tx.eventpublisher.event.TransactionalEvent class, than the event will be published immediately just like the Spring org.springframework.context.ApplicationEventPublisher should do.

Likewise, if we publish an event using it.diepet.spring.tx.eventpublisher.TransactionalEventPublisher in an operation executed outside a transaction, the event will be published immediately (even if the class event is a subclass of it.diepet.spring.tx.eventpublisher.event.TransactionalEvent).

Example:

public class ProductServiceImpl implements ProductService {

	@Autowired
	private TransactionalEventPublisher transactionalEventPublisher;

	@Transactional
	public void f() {
		
		// some db stuff
		
		// the event will be published after that the transaction completes successfully
		transactionalEventPublisher.publishEvent(new CustomTransactionalEvent("Launched f()"));
		
		// some db stuff
	}

	public void g() {
		
		// the event will be published immediately, 
		// because g() does not have a @Transactional annotation
		transactionalEventPublisher.publishEvent(new CustomTransactionalEvent("Launched g()"));
		
	}


} 

License

This project is licensed under the terms of the MIT license.

About

A plugin for Spring Framework 3.2 for publishing events only after a successfull transaction

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages