Friday, 11 October 2013

What is a transaction ?


A business system transaction is the execution of a unit-of-work that accesses one or more shared resources, usually databases. A unit-of-work is a set of activities that relate to each other and must be completed together. The reservation process is a unit-of-work made up of several activities: recording a reservation, debiting a credit card, and generating a ticket.

Characteristics of a Transaction

There are four characteristics of a transaction that must be met for a system to be considered safe.

Atomic: An atomic transaction must execute completely or not at all. This means that every task within a unit-of-work must execute without error. If any of the tasks fail, the entire unit-of-work or transaction is aborted, meaning that any changes to the data are undone. If all the tasks execute successfully, the transaction is committed, which means that the changes to the data are made permanent or durable.

Consistent: Consistency refers to the integrity of the underlying data store. It must be enforced by both the transactional system and the application developer. The transactional system fulfills this obligation by ensuring that a transaction is atomic, isolated, and durable. The application developer must ensure that the database has appropriate constraints (primary keys, referential integrity, and so forth) and that the unit-of-workthe business logicdoesn't result in inconsistent data (i.e., data that is not in harmony with the real world it represents). In an account transfer, for example, the debit to one account must equal the credit to another account.

Isolated: Isolation means that a transaction must be allowed to execute without interference from other processes or transactions. In other words, the data that a transaction accesses cannot be affected by any other part of the system until the transaction or unit-of-work is completed.

Durable: Durability means that all the data changes made during the course of a transaction must be written to some type of physical storage before the transaction is successfully completed. This ensures that the changes are not lost if the system crashes.

Transaction Isolation

There are three problems for transaction isolation .
Dirty read problem: A dirty read occurs when a transaction reads uncommitted changes made by a previous transaction. If the first transaction is rolled back, the data read by the second transaction becomes invalid because the rollback undoes the changes. The second transaction will not be aware that the data it has read has become invalid.

Non-Repeatable Read problem:  Unrepeatable read occurs when a component reads some data from a database, but upon rereading the data, the data has been changed. This can arise when another concurrently executing transaction modifies the data being read.

Suppose you read a data set x from the database.  Another application overrides data set x with new values.  Now you reread the data set x from the database. You will see that the values have magically changed.

We need to address this problem if you want to read each of the rows that we are modifying, and then be able to update each row, knowing that none of the rows are being modified by other concurrent transaction.

Phantom read problem: A phantom is a new set of data that magically appears in a database between two read operations.

Suppose our application queries the database using some criteria and retrieves a dataset.   Another application inserts new data that satisfy our query. When we perform the query again then new set of data will magically appeared.

Database Locks 

There are four types of locks .

Read locks: Read locks prevent other transactions from changing data, read during a transaction until the transaction ends, thus preventing nonrepeatable reads. Other transactions can read the data but not write to it. The current transaction is also prohibited from making changes. Whether a read lock locks only the records read, a block of records, or a whole table depends on the database being used.

Write locks: Write locks are used for updates. A write lock prevents other transactions from changing the data until the current transaction is complete but allows dirty reads by other transactions and by the current transaction itself. In other words, the transaction can read its own uncommitted changes.

Exclusive write locks: Exclusive write locks are used for updates. An exclusive write lock prevents other transactions from reading or changing the data until the current transaction is complete. It also prevents dirty reads by other transactions. Some databases do not allow transactions to read their own data while it is exclusively locked.

Snapshots: A snapshot is a frozen view of the data that is taken when a transaction begins. Some databases get around locking by providing every transaction with its own snapshot. Snapshots can prevent dirty reads, nonrepeatable reads, and phantom reads. They can be problematic because the data is not real-time data; it is old the instant the snapshot is taken.


Transaction Isolation Levels

Transaction isolation is defined in terms of the isolation conditions (dirty reads, repeatable reads, and phantom reads). Isolation levels are commonly used in database systems to describe how locking is applied to data within a transaction.

Read Uncommitted: The transaction can read uncommitted data (i.e., data changed by a different transaction that is still in progress). Dirty reads, nonrepeatable reads, and phantom reads can occur. Bean methods with this isolation level can read uncommitted changes.

Read Committed : The transaction cannot read uncommitted data; data that is being changed by a different transaction cannot be read. Dirty reads are prevented; nonrepeatable reads and phantom reads can occur. Bean methods with this isolation level cannot read uncommitted data.

Repeatable Read : The transaction cannot change data that is being read by a different transaction. Dirty reads and nonrepeatable reads are prevented; phantom reads can occur. Bean methods with this isolation level have the same restrictions as those in the Read Committed level and can execute only repeatable reads.

Serializable: The transaction has exclusive read and update privileges; different transactions can neither read nor write to the same data. Dirty reads, nonrepeatable reads, and phantom reads are prevented. This isolation level is the most restrictive.

Isolation Level
Transactions
Dirty Reads
Non-Repeatable Reads
Phantom Reads
TRANSACTION_NONE
Not supported
Not applicable
Not applicable
Not applicable
READ_COMMITTED
Supported
Prevented
Allowed
Allowed
READ_UNCOMMITTED
Supported
Allowed
Allowed
Allowed
REPEATABLE_READ
Supported
Prevented
Prevented
Allowed
SERIALIZABLE
Supported
Prevented
Prevented
Prevented

Usually, you do not need to do anything about the transaction isolation level; you can just use the default one for your DBMS. The default transaction isolation level depends on your DBMS. For example, for Java DB, it is TRANSACTION_READ_COMMITTED. JDBC allows you to find out what transaction isolation level your DBMS is set to  (using   the Connection method getTransactionIsolation) and also allows you to set it to another level (using the Connection methodsetTransactionIsolation).


Tuesday, 8 October 2013

Hibernate Caching



        Hibernate has two kinds of cache, which are the first-level cache and the second-level cache. We also call the first-leve cache session cache, and the second-level cache process-level cache. The first-level cache is mandatory and can’t be turned off; However, the second-level cache in Hibernate is optional. Because the process-level cache caches objects across sessions and has process or cluster scope, in some situation, turning on the process-level cache can improve the performance of the application. In fact, before accessing the database to load an object, Hibernate will first look in the Session cache and then in the process-level cache.

Query cache
If you have queries that run over and over, with the same parameters, query caching provides performance gains.  Caching introduces overhead in the area of transactional processing. For example, if you cache results of a query against an object, Hibernate needs to keep track of whether any changes have been committed against the object, and invalidate the cache accordingly. In addition, the benefit from caching query results is limited, and highly dependent on the usage patterns of your application. For these reasons, Hibernate disables the query cache by default.
Enabling the query cache
1.      Set the hibernate.cache.use_query_cache property to true.This setting creates two new cache regions:
org.hibernate.cache.internal.StandardQueryCache holds the cached query results.
 org.hibernate.cache.spi.UpdateTimestampsCache holds timestamps of the most recent updates to queryable tables. These timestamps validate results served  from the query cache.
2.     Adjust the cache timeout of the underlying cache region
If you configure your underlying cache implementation to use expiry or timeouts, set the cache timeout of the underlying cache region for the UpdateTimestampsCache to a higher value than the timeouts of any of the query caches. It is possible, and recommended, to set the UpdateTimestampsCache region never to expire. To be specific, a LRU (Least Recently Used) cache expiry policy is never appropriate. 3. Enable results caching for specific queries
Since most queries do not benefit from caching of their results, you need to enable caching for individual queries, e ven after enabling query caching overall. To enable results caching for a particular query, call org.hibernate.Query.setCacheable(true). This call allows the query to look for existing cache results or add its results to the cache when it is executed.
The query cache does not cache the state of the actual entities in the cache. It caches identifier values and results of value type. Therefore, always use the query cache in conjunction with the second-level cache for those entities which should be cached as part of a query result cache.
Query cache regions
For fine-grained control over query cache expiration policies, specify a named cache region for a particular query by calling Query.setCacheRegion().
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();
To force the query cache to refresh one of its regions and disregard any cached results in the region, call org.hibernate.Query.setCacheMode(CacheMode.REFRESH). In conjunction with the region defined for the given query, Hibernate selectively refreshes the results cached in that particular region. This is much more efficient than bulk eviction of the region via org.hibernate.SessionFactory.evictQueries().

Second-level cache(process scoped cache)
A hibernate SessionFactory aims to create sessions, initializes JDBC connections and pool them. The second level cache lives in the SessionFactory level so all session can share it. This is why it’s called a process scoped cache. The second level cache is not enabled by default. One has to configure the cache strategy for hibernate entities and the cache provider.
By default, entities are not part of the second-level cache, and their use is not recommended. If you absolutely must use entities, set the shared-cache-mode element in persistence.xml, or use property javax.persistence.sharedCache.mode in your configuration.
 Possible values for Shared Cache Mode
ENABLE_SELECTIVE: Entities are not cached unless you explicitly mark them as cacheable. This is the default and recommended value.
DISABLE_SELECTIVE: Entities are cached unless you explicitly mark them as not cacheable.
ALL:  All entities are always cached even if you mark them as not cacheable.
NONE: No entities are cached even if you mark them as cacheable. This option basically disables second-level caching.

 Caching strategies
read-only : A read-only cache is good for data that needs to be read often but not modified. It is simple, performs well, and is safe to use in a clustered environment.
nonstrict read-write :Some applications only rarely need to modify data. This is the case if two transactions are unlikely to try to update the same item simultaneously. In this case, you do not need strict transaction isolation, and a nonstrict-read-write cache might be appropriate. If the cache is used in a JTA environment, you must specify hibernate.transaction.manager_lookup_class. In other environments, ensore that the transaction is complete before you call Session.close() or Session.disconnect().
read-write :A read-write cache is appropriate for an application which needs to update data regularly. Do not use a read-write strategy if you need serializable transaction isolation. In a JTA environment, specify a strategy for obtaining the JTA TransactionManager by setting the property hibernate.transaction.manager_lookup_class. In non-JTA environments, be sure the transaction is complete before you call Session.close() or Session.disconnect().
To use the read-write strategy in a clustered environment, the underlying cache implementation must support locking. The build-in cache providers do not support locking.
transactional :The transactional cache strategy provides support for transactional cache providers such as JBoss TreeCache. You can only use such a cache in a JTA environment, and you must first specify hibernate.transaction.manager_lookup_class.
Second-level cache providers for Hibernate Cache Interface Supported strategies
Strategy/Provider
Read-only
Nonstrictread-write
Read-write
Transactional
EHCache
X
X
X

OSCache
X
X
X

SwarmCache
X
X


JBoss Cache
X


X
HashTable (testing only)
X
X
X

Configuring cache providers
You will specify a cache provider in hibernate.cfg.xml configuration file. We choose EHCache as our second-level cache provider:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   <property name="hibernate.dialect">
      org.hibernate.dialect.MySQLDialect
   </property>
   <property name="hibernate.connection.driver_class">
      com.mysql.jdbc.Driver
   </property>

   <!-- Assume students is the database name -->
   <property name="hibernate.connection.url">
      jdbc:mysql://localhost/test
   </property>
   <property name="hibernate.connection.username">
      root
   </property>
   <property name="hibernate.connection.password">
      root123
   </property>
   <property name="hibernate.cache.provider_class">
      org.hibernate.cache.EhCacheProvider
   </property>

   <!-- List of XML mapping files -->
   <mapping resource="Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>



Now, you need to specify the properties of the cache regions. EHCache has its own configuration file,ehcache.xml, which should be in the CLASSPATH of the application. A cache configuration in ehcache.xml for the Employee class may look like this:
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>

<cache name="Employee"
maxElementsInMemory="500"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>


Using annotations
@Entity 
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest { ... }
Using <cache> element in hbm.xml file

<cache
    usage="transactional"
    region="RegionName"
    include="all"
/>

Usage:The caching strategy. This attribute is required, and can be any of the following values.
o    transactional
o    read-write
o    nonstrict-read-write
o    read-only
Region: The name of the second-level cache region. This optional attribute defaults to the class or collection role name.
Include: Whether properties of the entity mapped with lazy=true can be cached when attribute-level lazy fetching is enabled. Defaults to all and can also be non-lazy.
Instead of <cache>, you can use <class-cache> and <collection-cache> elements inhibernate.cfg.xml.

 

Managing the caches
Whenever you pass an object to save(), update() or saveOrUpdate(), and whenever you retrieve an object using load(), get(), list(), iterate() or scroll(), that object is added to the internal cache of the Session.
When flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur, or if you are processing a huge number of objects and need to manage memory efficiently, the evict() method can be used to remove the object and its collections from the first-level cache.
ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
    Cat cat = (Cat) cats.get(0);
    doSomethingWithACat(cat);
    sess.evict(cat);
}
The Session also provides a contains() method to determine if an instance belongs to the session cache.
To evict all objects from the session cache, call Session.clear()
For the second-level cache, there are methods defined on SessionFactory for evicting the cached state of an instance, entire class, collection instance or entire collection role.
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
The CacheMode controls how a particular session interacts with the second-level cache:
o    CacheMode.NORMAL: will read items from and write items to the second-level cache
o    CacheMode.GET: will read items from the second-level cache. Do not write to the second-level cache except when updating data
o    CacheMode.PUT: will write items to the second-level cache. Do not read from the second-level cache
o    CacheMode.REFRESH: will write items to the second-level cache. Do not read from the second-level cache. Bypass the effect of hibernate.cache.use_minimal_puts forcing a refresh of the second-level cache for all items read from the database
To browse the contents of a second-level or query cache region, use the Statistics API:
Map cacheEntries = sessionFactory.getStatistics()
        .getSecondLevelCacheStatistics(regionName)
        .getEntries();
You will need to enable statistics and, optionally, force Hibernate to keep the cache entries in a more readable format:
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true

Session Cache

Fist level cache in hibernate is enabled by default and you do not need to do anything to get this functionality working. In fact, you can not disable it even forcefully.  it is associated with Session object. As we know session object is created on demand from session factory and it is lost, once the session is closed. Similarly, first level cache associated with session object is available only till session object is live. It is available to session object only and is not accessible to any other session object in any other part of application.
Important facts
1.       First level cache is associated with “session” object and other session objects in application can not see it.
2.       The scope of cache objects is of session. Once session is closed, cached objects are gone forever.
3.       First level cache is enabled by default and you can not disable it.
4.       When we query an entity first time, it is retrieved from database and stored in first level cache associated with hibernate session.
5.       If we query same object again with same session object, it will be loaded from cache and no sql query will be executed.
6.       The loaded entity can be removed from session using evict() method. The next loading of this entity will again make a database call if it has been removed using evict() method.
7.       The whole session cache can be removed using clear() method. It will remove all the entities stored in cache. evict() is used to remove a particular object from cache associated with session, and clear() method is used to remove all cached objects associated with session. 



Friday, 27 September 2013

Defining and Starting a Thread

An application that creates an instance of Thread must provide the code that will run in that thread. There are two ways to do this:

  • Provide a Runnable object. The Runnable interface defines a single method, run, meant to contain the code executed in the thread. The Runnableobject is passed to the Thread constructor, as in the HelloRunnable example:
 
public class HelloRunnable implements Runnable {
 
    public void run() {
        System.out.println("Hello from a thread!");
    }
 
    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
 
}
  • Subclass Thread. The Thread class itself implements Runnable, though its run method does nothing. An application can subclass Thread, providing its own implementation of run, as in the HelloThread example:
public class HelloThread extends Thread {
 
    public void run() {
        System.out.println("Hello from a thread!");
    }
 
    public static void main(String args[]) {
        (new HelloThread()).start();
    }
 
}

Notice that both examples invoke Thread.start in order to start the new thread.


 Differences between Thread and Runnable interface.

1) Java doesn't support multiple inheritance, which means you can only extend one class in Java so once you extended Thread class you lost your chance and can not extend or inherit another class in Java.

2) In Object oriented programming extending a class generally means adding new functionality, modifying or improving behaviors. If we are not making any modification on Thread than use Runnable interface instead.

3) Runnable interface represent a Task which can be executed by either plain Thread or Executors or any other means. so logical separation of Task as Runnable than Thread is good design decision.

4) Separating task as Runnable means we can reuse the task and also has liberty to execute it from different means. since you can not restart a Thread once it completes. again Runnable vs Thread for task, Runnable is winner.

5) Java designer recognizes this and that's why Executors accept Runnable as Task and they have worker thread which executes those task.

6) Inheriting all Thread methods are additional overhead just for representing a Task which can can be done easily with Runnable.