Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Monday, September 14, 2015

Configuring Multiple Transaction Managers with @Transactional Annotation

Most of the time Spring applications are working with a single transaction manager, but in some cases applications may have to work with multiple transaction managers.

Suppose an application have to access two databases, "ApplicationDB" and "ApplicatioinDataDB". In here the application should contain two separate data sources and each data source should be accessible via two independent transaction mangers.



In this case, optional value attribute in @Transactional annotation can be used to specify the PlatFormTransactionManager to be used. The value can either be bean name or qualifier value of the transaction manager bean.

Qualifier annotation can be used as follows:

public class ApplicationService {
  
    @Transactional("txGeneral")
    public void setApplicationMetaData(String name) { ... }
  
    @Transactional("txData")
    public void setAppData() { ... }
  }

Transaction manager beans can be defined as follows in the application context:

<tx:annotation-driven/>

  <bean id="transactionManager1" class="org.springframework.jdbc.DataSourceTransactionManager">
    ...
    <qualifier value="txGeneral"/>
  </bean>

  <bean id="transactionManager2" class="org.springframework.jdbc.DataSourceTransactionManager">
    ...
    <qualifier value="txData"/>
  </bean> 

In here both transactioin methods will run under separate transaction managers in separate sessions. The default <tx:annotation-driven> target bean name transactionManager will still be used if no specifically qualified PlatformTransactionManager bean is found.

If the application have to perform cross database transactions, it is better to stick with JTA rather than having separate transaction mangers, because rollback propagation in one transaction running under a transaction manger will not rollback other transaction manager's transaction. Therefore cross database transactions will not be atomic. More about this later....

Saturday, July 25, 2015

Write logs to different outputs according to log level

In some cases we have to write logs to different outputs according to log level. It can be easily configured by specifying the filter of certain appenders. The most easiest way of specifying appenders is having a properties configuration file, but properties configuration files doesn’t support log level filters. Therefore it is necessary to stick with XML to specify appenders.

Log4J supports different log levels. These log levels can be used in different events as mentioned in table 1.

#
Level
Summary
1
ALL
ALL has the lowest rank and it is intended to turn on all logging.
2
DEBUG
DEBUG level is useful to developers to indentify events in an informational manner and allows to debug the application.
3
ERROR
ERROR level specifies events that must immediately investigated but which allows the application to continue its functionality.
4
FATAL
FATAL level can be used to log terrible errors that can cause application to abort its operations.
5
INFO
INFO level is useful to mention informative messages after important process has finished.
6
OFF
OFF has the highest rand and it is intended to turn off all logging.
7
TRACE
TRACE level is used to log events in a very informative manner. Basically TRACE logs are used in development and eventually remove from production deployments.
8
WARN
WARN level can be used to log potentially harmful situations.

Basically when a low priority log level is given, messages with higher priority for the given log level are also logged. In that case log level range filter (LevelRangeFilter) can be used to reject messages with priorities outside a certain range. The range can be configured by specifying the values for LevelMin, LevelMax, and AcceptOnMatch properties.

A sample of log4j XML file with log level filters created by a colleague is added below.


References:
  • "Logging Services." Log4J. Apache Software Foundation, n.d. Web.
  • "Log4j Architecture." Log4J. Apache Software Foundation, n.d. Web.

Tuesday, May 5, 2015

Java Messaging Service (JMS) - I

JMS is a collection of interfaces that define the specifications of messaging clients to use when there are communicating with messaging systems. It is much similar to the way JDBC abstract relational database access.
JMS API supports three major types of messaging systems. Those are General messaging applications, Point-to-Point applications and Publish-Subscribe applications. In order to build a general messaging application, there are few components/interfaces that the application should adhere to its implementation,
  • ConnectionFactory
  • Destination
  • Connection
  • Session
  • Message
  • MessageProducer
  • MessageConsumer

According to JMS specifications, both ConnectionFactory and Destination should be obtained through JNDI. Other objects can create with JMS vendor implementations. The sequence is like as follows, once we have a ConnectionFactory, we can create a Connection. With a Connection, we can create a Session. Once we have a Session, we can create a Message, MessageProducer or a MessageConsumer.
Overview of a general JMS application.


Here below I have attached a github link to a demo application that demonstrates the above connectivity.

GitHub repo: https://github.com/rootpox/JBoss-A-MQ-MessagingQueue

Image reference: Mark Richards, 2009. Java Message Service. Second Edition Edition. O'Reilly Media.