Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Transaction management in JPA/Spring

Propagation is used to define how transactions related to each other. Common options

  • Required: Code will always run in a transaction. Create a new transaction or reuse one if available.
  • Requires_new: Code will always run in a new transaction. Suspend current transactions if one exists.


Isolation Defines the data contract between transactions.

  1. Read Uncommitted: Allows dirty reads
  2. Read Committed: Does not allow dirty reads
  3. Repeatable Read: If a row is read twice in the same transaction, the result will always be the same
  4. Serializable: Performs all transactions in a sequence


An isolation level is about how much a transaction may be impacted by the activities of other concurrent transactions. It supports consistency leaving the data across many tables in a consistent state. It involves locking rows and/or tables in a database.

The problem with multiple transactions
  • Scenario 1. If the T1 transaction reads data from table A1 that was written by another concurrent transaction T2. If on the way T2 is a rollback, the data obtained by T1 is an invalid one. E.g a=2 is original data. If T1 read a=1 that was written by T2.If T2 rollback then a=1 will be a rollback to a=2 in DB. But, Now, T1 has a=1 but in the DB table, it is changed to a=2.
  • Scenario2.If a T1 transaction reads data from table A1.If another concurrent transaction(T2) updates data on table A1. Then the data that T1 has read is different from table A1. Because T2 has updated the data in table A1.E.g if T1 read a=1 and T2 updated a=2.Then a!=b.
  • Scenario 3. If the T1 transaction reads data from table A1 with a certain number of rows. If another concurrent transaction(T2) inserts more rows on table A1. The number of rows read by T1 is different from the rows in table A1


Scenario 1 is called Dirty reads.
Scenario 2 is called Non-repeatable reads.
Scenario 3 is called Phantom reads.

So, the isolation level is the extent to which Scenario 1, Scenario 2, and Scenario 3 can be prevented. You can obtain a complete isolation level by implementing locking. That is preventing concurrent reads and writes to the same data from occurring. But it affects performance. The level of isolation depends upon application to application on how much isolation is required.


  1. ISOLATION_READ_UNCOMMITTED: Allows to read changes that haven’t yet been committed. It suffers from Scenario 1, Scenario 2, Scenario 3
  2. ISOLATION_READ_COMMITTED: Allows reads from concurrent transactions that have been committed. It may suffer from Scenario 2 and Scenario 3. Because other transactions may be updating the data.
  3. ISOLATION_REPEATABLE_READ: Multiple reads of the same field will yield the same results until it is changed by themselves.It may suffer from Scenario 3. Because other transactions maybe inserting the data
  4. ISOLATION_SERIALIZABLE: Scenario 1,Scenario 2,Scenario 3 never happens.It is complete isolation. It involves full locking. It affects performance because of locking.

Spring part 1 [IOC Containers]


IOC container contains two types of containers which are core container and another is advanced J2EE container. Core container is called BeanFactory and J2EE container is called ApplicationContext also one more Configurable Application Context.

So we may be thinking like what actually the containers do?

  1. They create a instances for the POJO classes.
  2. manage lifecycle of POJO classes.
  3. they can also do dependency Injection in POJO classes.


Then there may be a question what is the difference between the two types of containers? Here the core containers will initialize the object upon the user request where as the ApplicationContext will create the object at the compile time to be used for the user. Lets say we have a class named Demo. Now lets say we are defining the beans of the Demo in the xml file like

...
<beans>
    <bean id="demo" class="Demo" />
</beans>
...

Lets say while using the application user need the object the Demo then using the core container the IOC will create a new object for the user only when user request for it. But the ApplicationContext will eagerly creates the object while running the app and when user want the object it will provide the created or provide the reference of the created object to the user. By default the the bean creation scope is singleton which means it can be created only once and later whoever want that object it will reference the previous of firstly created object. But we can use several scopes methods like prototype, session, global session etc. Fo example if we have used the prototype scope then the IOC will create the new object upon each user requests, but will not create any object at the beginning.

...
<beans>
    <bean id="demo" class="Demo"  scope="prototype"/>
</beans>
...


1. Bean Factory Container

public static void main(String args[]){
   Resource res = new ClassPathResource("YOUR_XML_FILE_NAME.xml");
   BeanFactory factory = new XmlBeanFactory(res);
   Demo d = (Demo) factory.getBean("demo"); //typeCast because factory always return Object type
}

2. ApplicationContext Container

public static void main(String args[]){
  ApplicationContext app = new ClassPathXmlApplicaitonContext("some_location/your_xml_file.xml");
  Demo d = (Demo)  app.getBean("demo");
}


How the IOC creates the object ?
1. User request IOC to provide the instance of some class by using the bean id/name
2. Then IOC will look up for the bean with given id/name in the bean configuration file and take the name of the class
3. It execute the method called Class.forName("Demo").newInstance();