Tuesday 12 December 2017

Transactions

  • Hybris allows to use the transaction system of the underlying database through a simple-to-use API. 
  • Do not have to look up a transaction object from a JNDI tree. 
  • Simply employ begin, commit, and rollback statements in your code.

Every thread in Hybris has a Transaction object.
To get this Transaction object, 
Transaction tx = Transaction.current();
Getting the Transaction object does not trigger a transaction begin. 
You will need to explicitly trigger transactions via the begin(), commit(), and rollback() methods.
tx.begin(); 
boolean success = false;
try {
// do business logic
doSomeBusinessLogic();
success = true;
} finally {
if( success )
tx.commit();
else
tx.rollback();
}

Always Use Finally Blocks!
During transaction execution, there may be issues which do not result in an Exception, but in an ErrorThe finally statement will be executed if Errors arise, and can rollback the transaction. Then the DB is in a consistent state again, and the connection to the DB will be closed.

Since there is only one Transaction object for every single thread, using several instances of the Transaction object will not result in different actual Transaction objects. 

Nested Transactions
The nested transaction will not start an individual transaction, but will be executed in the context of the transaction of the calling method. 

Using TransactionBody
Hybris offers an encapsulation for the Transaction object begin(), commit(), and rollback() methods. 
By instantiating a TransactionBody object and overriding the TransactionBody execute() method, you can encapsulate the entire transaction process.
Transaction.current().execute( new TransactionBody() {
public Object execute() {
.....      
}
});
Delayed Store
By default, Hybris executes every statement as soon as it comes up. If "Delayed-store" is activated all DB modification statements done by a transaction are kept in memory until the transaction is actually flushed and then executed at once. 

Disadvantage: Since all of the DB modification statements are executed at once, no data changes will take place until the transaction is actually flushed. 

* To flush transaction in delayed-store mode, call the flushDelayedStore() of Transaction object:
tx.flushDelayedStore();
* There are two ways of setting whether or not to use delayed-store.
- transaction.delayedstore property in project.properties file - sets the global default value for delayed-store transactions. 
- enableDelayedStore( Boolean) method of Transaction object - The value of the delayed-store transactions method is valid until the transaction is committed (or rolled back), and is reset to the global default afterwards.

- true: enables delayed-store transactions
- false: disables delayed-store transactions

Transaction Isolation
READ_COMMITTED is the transaction isolation level used by transactions in Hybris. 

Intra Transaction Cache
It is possible to cache data manually for each transaction. 
Use the Transaction.set/getContextEntry(Object, Object) for storing data only for one transaction. 
This data is reset to null whenever commit() or rollback() is called.
tx.setContextEntry("mykey","myvalue");

Using Transactions via Spring
The HybrisTransactionManager implements the Spring PlatformTransactionManager registered at the core application context delegating all transaction calls to the Hybris transaction framework. 
You can use the Spring Transaction Framework by:
  • Using @Transaction annotation
  • AOP-style transaction declaration (using tx schema)
  • Using TransactionTemplate

TransactionTemplate mechanism
  1. Inject or get the configured transaction manager
  2. Instantiate a new template
  3. Call the template execute method by defining a new body
// 1.
PlatformTransactionManager manager = 
(PlatformTransactionManager) Registry.getApplicationContext().getBean("txManager");
// 2.
TransactionTemplate template = new TransactionTemplate(manager);
// 3.
template.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(final TransactionStatus status) {
// do something transactional
}
});

No comments:

Post a Comment