TransactionTemplate

The use of thread-safe TransactionTemplate helps developers get rid of boilerplate code, as we already discussed with JdbcTemplate. It makes the programmatic transaction management simple yet powerful with the help of callback methods. Using TransactionTemplate becomes easy as it has different setter methods to customize various transaction properties such as isolation level, propagation behavior, and so on. The first step to use TransactionTemplate is to get its instance by providing transaction manager. The second step is to get an instance of TransactionCallback that can be passed to the execute method. The following example will demonstrate how to use the template where we don't have to create TransactionDefinition as we did in the Ch05_PlatformTransactionManager application:

  1. Create a Java application named Ch05_TransactionTemplate and copy all the required jars, which we added earlier in the application.
  2. We will keep the outline of the application the same as that of the Ch05_PlatformTransactionManager application, so you can copy the beans, DAO, and service package as it is. The only change that we will make is use TransactionTemplate instead of using PlatformTransactionManager in BookServiceImpl.
  3. From BookServiceImpl, delete the PlatformTransactionManager data member and add TransactionTemplate.
  4. Annotate it with @Autowired to use DI.
  1. We will update the searchBook() method to use TransactionTemplate by setting it as a read-only transaction using setReadOnly(true). TransactionTemplate has a callback method as execute(), where the business logic can be written to execute. The method is expecting an instance of TrasnsactionCallback, and it will return the object of the searched book. The code is written as follows:
@Service(value = "bookService") 
public class BookServiceImpl implements BookService { 
  @Autowired 
  TransactionTemplate transactionTemplate; 
 
  @Autowired 
  BookDAO bookDAO; 
 
  public Book searchBook(longISBN) { 
    transactionTemplate.setReadOnly(true); 
    returntransactionTemplate.execute(new 
      TransactionCallback<Book>()  
      { 
        @Override 
        public Book doInTransaction(TransactionStatusstatus) {  
          // TODO Auto-generated method stub 
          Book book = bookDAO.serachBook(ISBN); 
          return book; 
        } 
     }); 
  } 
}

To perform the task, we have created an instance of TransactionCallback by using the concept of inner class. The generic type specified here is Book as it is the return type of the searchBook() method. The class is overriding the doInTransaction() method to invoke the business logic from DAO's searchBook() method.

One more implementation of TransactionCallback can be written using TransactionCallbackWithoutResult. It can be used in case the service method is not returning anything or having void as its return type.

  1. Now, let's add the addBook() method. The very first thing we have to find using searchBook() is whether the book exists in a table or not. If Book doesn't exist, add it. However, as searchBook() has made the readonly transaction, we will need to change the behavior. As Add book has Boolean as its return type, we will use TransactionCallBack of Boolean type. The code is as follows:
@Override 
public boolean addBook(Book book) { 
  // TODO Auto-generated method stub 
  if (searchBook(book.getISBN()).getISBN() == 98564567l)  
  { 
    transactionTemplate.setReadOnly(false); 
    return transactionTemplate.execute(new 
    TransactionCallback<Boolean>()  
    { 
      @Override  
      public boolean doInTransaction(TransactionStatus 
      status) { 
        try { 
          int rows = bookDAO.addBook(book); 
          if (rows> 0) 
          return true; 
        } catch (Exception exception) { 
          status.setRollbackOnly(); 
        } 
        return false; 
      } 
    }); 
  } 
  return false; 
} 

The code clearly shows that TransactionTemplate gives us the power of changing the properties of the transaction; yet, internally manage the transaction without writing the boilerplate code as PlatformTransactionManager has to.

  1. In the same way, we can add the code for deleteBook and updateBook(). You can find the complete code in the source code.
  1. Copy connection_new.xml from Ch05_PlatformTransactionmanager in the classpath and add a bean for TransactionTemplate, as follows:
<bean id="transactionTemplate"class=  
  "org.springframework.transaction.support.TransactionTemplate"> 
  <property name="transactionManager" 
    ref="transactionManager"></property> 
</bean> 

We already had a bean for transactionManager, so we will not add it here again.

  1. Copy MainBookService_operations.java in the default package to test the code. We will get the code executed successfully.
  2. Before moving ahead, just modify the code of doInTransaction() of the searchBook() method as follows:
public Book doInTransaction(TransactionStatusstatus) { 
  //Book book = bookDAO.serachBook(ISBN); 
  Book book=new Book(); 
  book.setISBN(ISBN); 
  bookDAO.addBook(book); 
  return book; 
} 
  1. On execution, we will get the stack trace, which denotes that the read-only operations are not allowed to modify the data like this:
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.125.219