Wednesday, December 18, 2013

Quartz Scheduler in Spring

 Quartz Scheduler is used to scheduling of all kinds of jobs. For this it uses Trigger, Job and JobDetail objects
   
                                           

 JobDetail objects contain all information needed to run a job. The Spring Framework provides a JobDetailBean that makes the JobDetail more of an actual JavaBean with sensible defaults

For Ex:
<bean name="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="example.ExampleJob" />
<property name="jobDataAsMap">
<map>
<entry key="timeout" value="5" />
</map>
</property>
</bean>

The timeout is specified in the job data map. The job data map is available through the JobExecutionContext (passed to you at execution time), but the JobDetailBean also maps the properties from the job data map to properties of the actual job. So in this case, if the ExampleJob contains a property named timeout,the JobDetailBean will automatically apply it.
Ex:

package example;
public class ExampleJob extends QuartzJobBean {
private int timeout;
/**
* Setter called after the ExampleJob is instantiated
* with the value from the JobDetailBean (5)
*/
public void setTimeout(int timeout) {
this.timeout = timeout;
}
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
// do the actual work
}
}

MethodInvokingJobDetailFactoryBean:
Oftenly we need to invoke a method on a specific Class. The
"MethodInvokingJobDetailFactoryBean" can do this exactly. 

Ex Configuration:

<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject" />
<property name="targetMethod" value="doIt" />
</bean>

The above example will call the doIt method on the ExampleBusinessObject class.
The class:

public class ExampleBusinessObject {
// properties and collaborators
public void doIt() {
// do the actual work
}
}

Using the MethodInvokingJobDetailFactoryBean, we don't need to create one-line jobs that just invoke a method, and we only need to create the actual business object and wire up the detail object.

By default Quartz jobs are stateless. Since they are stateless there is a possibility of interfering each other.

If we specify 2 triggers for the same JobDetails there is a possibility of starting the second one before First one is Completed.

To avoid this and to make jobs of 'MethodInvokingJobDetailFactoryBean'  
non-concurrent set 'concurrent' flag to 'false'.


<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="exampleBusinessObject" />
<property name="targetMethod" value="doIt" />
<property name="concurrent" value="false" />
</bean>

Wiring up jobs using triggers & the 'SchedulerFactoryBean':

We have created JobDetails and Jobs.
we still needs to schedule the jobs themselves this can be done using 'triggers' and a 'SchedulerFactoryBean'.
There are several triggers are available with in Quartz and Spring Provides 2 Quartz FactoryBean implementations with convenient defaults

CronTriggerFactoryBean
SimpleTriggerFactoryBean.

Triggers need to be Scheduled.For this Spring offers a 'SchedulerFactoryBean' that exposes triggers to be set as properties.
SchedulerFactoryBean schedules the actual jobs with those triggers.

Ex. Configurations:

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<!-- see the example of method invoking job above -->
<property name="jobDetail" ref="jobDetail" />
<!-- 10 seconds -->
<property name="startDelay" value="10000" />
<!-- repeat every 50 seconds -->
<property name="repeatInterval" value="50000" />
</bean>

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="exampleJob" />
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0 0 6 * * ?" />
</bean>

Now we've set up two triggers, 
First one running every 50 seconds with a starting delay of 10 seconds and
Second one runs every morning at 6 AM. And Finally we need to set up the

SchedulerFactoryBean:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
<ref nean="simpleTrigger"/>
</list>
</property>
</bean>

there are some more properties to use.

Scheduling in Spring

 The Spring Framework provides abstractions for asynchronous execution and scheduling of tasks with the 'TaskExecutor' and 'TaskScheduler' ibsp;                                                                                     Spring also Provided Implementations of these Interfaces which supports  'Thread Pools' or delegation to CommonJ within an application server environment.

Spring also features integration classes for supporting scheduling with the Timer, part of the JDK since1.3, and the Quartz Scheduler.

Both of those schedulers are set up using a FactoryBean with optional references to Timer or Trigger instances, respectively. And, a convenience class for both the Quartz Scheduler and the Timer is available that allows you to invoke a method of an existing target object (analogous to the normal MethodInvokingFactoryBean operation).

Spring's TaskExecutor interface has a single method execute(Runnable task) that accepts a task for execution based on the semantics and configuration of the thread pool.

The TaskExecutor was originally created to give other Spring components an abstraction for thread pooling where needed. Components such as the ApplicationEventMulticaster, JMS's AbstractMessageListenerContainer, and Quartz integration all use the TaskExecutor abstraction to pool threads. However, if your beans need thread pooling behavior, it is possible to use this abstraction for your own needs.

TaskExecutor types:
There are a number of pre-built implementations of TaskExecutor

SimpleAsyncTaskExecutor
SyncTaskExecutor
ConcurrentTaskExecutor
and etc.

Using a TaskExecutor:
Spring's TaskExecutor implementations are used as simple JavaBeans
as Following

import org.springframework.core.task.TaskExecutor;

public class TaskExecutorExample {
private class MessagePrinterTask implements Runnable {
private String message;
public MessagePrinterTask(String message) {
this.message = message;
}
public void run() {
System.out.println(message);
}
}
private TaskExecutor taskExecutor;
public TaskExecutorExample(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
public void printMessages() {
for(int i = 0; i < 25; i++) {
taskExecutor.execute(new MessagePrinterTask("Message" + i));
}
}
}

As you can see, rather than retrieving a thread from the pool and executing yourself, you add your Runnable to the queue and the TaskExecutor uses its internal rules to decide when the task gets
executed.
To configure the rules that the TaskExecutor will use, simple bean properties have been exposed.

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="queueCapacity" value="25" />
</bean>
<bean id="taskExecutorExample" class="TaskExecutorExample">
<constructor-arg ref="taskExecutor" />
</bean>

Task Scheduler:

In addition to the 'TaskExecutor' abstraction, Spring 3.0 introduces a TaskScheduler with a variety of methods for scheduling tasks to run at some point in the future.

Methods in TaskScheduler Interface

ScheduledFuture schedule(Runnable task, Trigger trigger);
ScheduledFuture schedule(Runnable task, Date startTime);
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);

The simplest method is the one named 'schedule' that takes a Runnable and Date only. That will cause the task to run once after the specified time. All of the other methods are capable of scheduling tasks to run repeatedly. The fixed-rate and fixed-delay methods are for simple, periodic execution, but the method that accepts a Trigger is much more flexible.

Trigger:

public interface Trigger {
Date nextExecutionTime(TriggerContext triggerContext);
}

The 'TriggerContex' is the most important part. It encapsulates all of the relevant data.The 'TriggerContext' is an interface (a 'SimpleTriggerContext' implementation is used by default). The methods are available for Trigger implementations.

public interface TriggerContext {
Date lastScheduledExecutionTime();
Date lastActualExecutionTime();
Date lastCompletionTime();
}

Trigger implementations:

Spring provides two implementations of the Trigger interface. The most interesting one is the
CronTrigger. It enables the scheduling of tasks based on cron expressions. For example the following
task is being scheduled to run 15 minutes past each hour but only during the 9-to-5 "business hours"
on weekdays.

scheduler.schedule(task, new CronTrigger("* 15 9-17 * * MON-FRI"));

And Another Implementations is

implementation is a 'PeriodicTrigger' that accepts a fixed period, an
optional initial delay value, and a boolean to indicate whether the period should be interpreted as a fixed-rate or a fixed-delay.

Tuesday, December 17, 2013

Transaction Management in Spring

Transaction Management is one of the Best Features in Spring Framework now i am going to demonstrate in the following posts as Simple Concepts with Example Codes.

1. Introduction to Spring Transaction Management               

2. Transaction Models in Spring

3. Transaction Propagation in Spring

4. Examples on Spring Transaction Management(using xml & annotations)

5. Example on Spring Transaction Management with Hibernate and Mysql(using Annotations)

Example on Transaction Management with Spring+Hibernate+Mysql

In this post i would like to discuss about Spring Tx.Magmt with Annotations with "Spring + Hibernate + Mysql "
In this Example i take

Demo(I)                                                                                  
DemoBean(c)
DemoClient(c)
Spring.xml(Spring configuration file.)
hibernate.cfg.xml(Hibernate configuration file.)
Employee.hbm.xml(Hibernate Mapping File.)

Demo:
package p1;

public interface Demo {
 public void bm1()throws RuntimeException,Exception;
}

DemoBean:

package p1;

public class DemoBean implements Demo{
private SessionFactory sf;

/**
* @param sf the sf to set
*/
public void setSf(SessionFactory sf) {
this.sf = sf;
}

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void bm1()throws Exception {

Session session=sf.getCurrentSession();
int r1=session.createQuery("UPDATE Employee set salary=1 where sno=6").executeUpdate();
int r2=session.createQuery("UPDATE Employee set name='kkk' where sno=57").executeUpdate();

if(r1==0 || r2==0){
System.out.println("Tx is rolling back.");
throw new RuntimeException();
}else{
System.out.println("Tx is Committed");
}
}
}

Spring.xml:
<beans...
     .....>
    <tx:annotation-driven transaction-manager="hbt"/>

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
             <property name="configLocation" value="hibernate.cfg.xml"/>
             <property name="dataSource" ref="drds" />
    </bean>
 
    <bean id="drds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/TEST"/>
        <property name="username" value="username"/>
        <property name="password" value="password"/>
    </bean>
 
    <bean id="hbt" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
   
    <bean id="db" class="p1.DemoBean">
         <property name="sf" ref="mySessionFactory"/>
     </bean>
</beans>

hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/databasename</property>
<property name="hibernate.connection.username">username</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.autocommit">false</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="Employee.hbm.xml" />
</session-factory>
</hibernate-configuration>

Employee.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="p1.Employee" table="Employee" catalog="database name">
        <id name="sno" type="java.lang.Integer">
            <column name="sno" />
            <generator class="identity" />
        </id>
        <property name="name" type="string">
            <column name="name" length="30" not-null="true" />
        </property>
        <property name="salary" type="float">
            <column name="salary" precision="8" not-null="true" />
        </property>
        <property name="eid" type="int">
            <column name="eid" not-null="true" />
        </property>
    </class>
</hibernate-mapping>


DemoClient:
package p1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DemoClient {
public static void main(String s[]){
ApplicationContext ctx=new ClassPathXmlApplicationContext("Spring.cfg.xml");
Demo d=(Demo)ctx.getBean("db");
try {
d.bm1();
} catch (RuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Run it.

Monday, December 16, 2013

Examples on Spring Transaction Management


In Spring There are 2 ways to use Transaction Management

          1. Programmatic.                                    
          2. Declarative.

Programmatic Approach is outdated now so I don't want to Discuss it. So We move to Declarative Approach. In Declarative Approach There are 2 ways ...

      Using Xml Configurations.
      Using Annotations.

Let Me use 'Xml Configurations' in my following Eg. application.

Example on Spring Transaction Management using 'Xml Configurations':

In My Example i am taking

 Demo(I)
 DemoBean(C)
 Spring.cfg.xml(Spring configuration file)
 DemoClient(Class To Run Application)
 and mysql database.

Demo:
package p1;

public interface Demo {
public void bm1();
}

DemoBean:
package p1;

import org.springframework.jdbc.core.JdbcTemplate;
public class DemoBean implements Demo{
private JdbcTemplate jt;

/**
* @param jt the jt to set
*/
public void setJt(JdbcTemplate jt) {
this.jt = jt;
}

@Override
public void bm1() {
int r1=jt.update("insert into Employee (eid,name,salary) values(2012,'Arjun1',100000)");
int r2=jt.update("UPDATE Employee set salary=50000 where eid=2010");

if(r1==0 || r2==0){
System.out.println("Transaction is Rollbacked.");
throw new RuntimeException();
}else{
System.out.println("Tx is Committed.");
}
}
}

DemoClient:
package p1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class DemoClient {

public static void main(String s[]){

/*FileSystemResource res=new FileSystemResource("Spring.cfg.xml");
XmlBeanFactory factory=new XmlBeanFactory(res);
Demo d=(Demo)factory.getBean("tfb");
d.bm1();*/
ApplicationContext ctx=new FileSystemXmlApplicationContext("Spring.cfg.xml");
Demo d=(Demo) ctx.getBean("tfb");
d.bm1();
}
}

Note: You can use Either BeanFactory or ApplicationContext container.

Spring.cfg.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
....">

<bean id="dmds"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
 <property name="url" value="jdbc:mysql://localhost:3306/database name"/>
 <property name="username" value="username"/>
 <property name="password" value="password"></property>
</bean>

<bean id="dts" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource"><ref bean="dmds"/></property>
</bean>

<bean id="jt1" class="org.springframework.jdbc.core.JdbcTemplate">
   <property name="dataSource" ref="dmds"/>
</bean>
    <bean id="db" class="p1.DemoBean">
        <property name="jt" ref="jt1"/>
    </bean>

    <!-- Pointcut Advisor to apply Transaction Attributes. -->
    <bean id="tas" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
        <property name="properties">
            <props>
                <prop key="bm1">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
 
     <!-- Gives Proxy Object having Transaction Service. -->
    <bean id="tfb" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="target" ref="db"/>
        <property name="transactionManager" ref="dts"/>
        <property name="transactionAttributeSource" ref="tas"/>
    </bean>
 </beans>

Run it from DemoClient.

Example on Spring Transaction Management using  'Annotations':
In this Example I take..

 Demo(I)
 DemoBean(C)
 Spring.cfg.xml(Spring configuration file)
 DemoClient(Class To Run Application)
 and mysql database.

all are same as above Application Except these Changes

in DemoBean add @Transactional annotation on top of bm1() as shown below

 @Transactional(propagation=Propagation.REQUIRED)
   public void bm1()
  {.....
  .....
  ...}

2. The Spring Configuration file is as Follows
<beans....>
  <bean id="drds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/databasename"/>
        <property name="username" value="username"/>
        <property name="password" value="password"/>
    </bean>
 
    <bean id="txmgr" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="drds"/>
    </bean>

    <bean id="jt1" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="drds"/>
    </bean>
 
    <bean id="db" class="p1.DemoBean">
        <property name="jt" ref="jt1"/>
    </bean>
 
    <tx:annotation-driven transaction-manager="txmgr"/><!-- Enables Annotation Based Transaction Management. -->
</beans>


Run it with these Changes.

Transaction Propagation

   "Making a Business Method working with client supplied Transaction

    is called 'Transaction Propagation'."

There are 6 types of "Transaction Propagation" attributes..
                                                                                                 
1. REQUIRED

2. REQUIRES NEW

3. SUPPORTS

4. NOT SUPPORTED

5. MANDATORY

6. NEVER

REQUIRED: If Client Calls Service(Business) Method having this attribute with Transaction then Service Method runs with That Transaction else Service Method runs with new Transaction.This is Most Popularly used Attributed.

REQUIRES NEW: Service Method having this attribute Always Runs with new Transaction Even though  the Client calls with Transaction or without Transaction.

SUPPORTS: Service Method having this attribute
 runs with Transaction if Client Calls with Transaction.
 runs with out Transaction if Client Calls with out Transaction.

NOT SUPPORTED: Service Method having this attribute Always Runs with out Transaction Even though  the Client calls with Transaction or without Transaction.

MANDATORY: The Client Should always call Service Method having this attribute with Transaction otherwise Exception will be raised.

NEVER: The Client Should always call Service Method having this attribute with out Transaction otherwise Exception will be raised.

NOTE: The Programmatic Transaction Management approach Does not support to this Transaction Propagation where Declarative Transaction Management Supports.


Saturday, December 14, 2013

Transaction Models

There are 2 Types of Transaction Models

 1. Flat Transactions.                                                            

 2. Nested Transactions.

A Flat Transaction is One Which Treats all operations of a transaction as one transaction,and if one operations fails then the entire Transaction will be Rolled back.

Transaction{

Operation 1

Operation 2

Operation 3

     .
     .

}

If any one of the above operations failed then the entire transaction will be rolled back.

A Nested Transaction is one which Considers each operation in Transaction as sub Transaction of that Main Transaction.If any one of the Sub Transaction(operation) fails no impact on the Main Transaction.

Main Transaction{

sub transaction 1{
Operation 1
}

sub transaction 2{
Operation 2
}

sub transaction 3{
Operation 3
}

     .
     .

}

If any one of the above sub Transaction failed no Effect on Main Transaction.

NOTE: Spring, EJB and Hibernate Supports Flat Transactions.
       Only Spring supports Nested Transactions.  

Friday, December 13, 2013

Spring Transaction Management with Mysql Rollback is not working


Yesterday i had struggle with 'Spring Transaction management'  that i am not able to Rollback Transaction.Now I Found the solution in My case...
 
In Mysql Database the 'MyISAM' Engine do not have transactions. So no matter how you configure spring or native JDBC without Spring or use JTA or Hibernate, you can never get a ROLLBACK.                                                            

In My case the Problem is ..
"My Database Table has 'MyIsam'  Engine and I Changed it to 'InnoDB' and then The 'Rollback' Worked Fine".

and one more possible solution is Try  set auto commit false.

Introduction to Transaction Management in Spring


"The Process Of Combining Related Operations into Single Unit and Execute Them in 'Do Every Thing or Nothing' Manner Called 'Transaction Management'".

Transaction Management have 3 Phases..

  •  Start Transaction.
  •  Process Transaction.
  •  Commit or Rollback Transaction.
As shown in the above Diagram...  Based on the Instruction coming from "Transactional Component" the 'TransactionManager' commit or rollback the application data into Database(resource) through 'Resource Manager'.

NOTE: The Application in which Transaction Management is enabled is known as 'Transactional Component or Transactional App'.

Types of Transactions:

Based on The Number of resources(Database) involved Transactions are Categorized into 2 Types

1. Local Transactions.
2. Global or Distributed Transactions.

If there is only one Resource(Database) Involved in Transaction Then That Transaction is Called Local Transaction.
Ex: Transferring Money Between Same Bank Accounts.

If There are Multiple Types of Resources(Databases) or Number of Same Type Resources(Databases) Involved in Transaction that Transaction is Called Global or Distributed Transaction.
Ex: Transferring Money Between Different Bank Accounts.

Global or Distributed Transaction Works By Using "2PC(2 Phase Commit.)" Protocol,
There are 2 Levels in This Protocol

   In 1st level The Distributed Transaction Manager seeks Permission  
   from the resources(Databases) to commit the Transaction.

   In 2nd Level if all the resources gives Permission to Commit then
   the Distributed Transaction will be Committed otherwise it will be
   rolled back.

The flow of 2PC Protocol



Spring, EJB and Hibernate Supports Local Transactions.
Only Spring and EJB supports Global or Distributed Transactions.

next>>