Transaction overview

Before starting with the details, we need to understand the basic terminologies. A transaction is a working unit, a set of operations that can succeed or fail in a single atomic unit. Transactions ensure that a unit is either completely executed or completely rolled back. Transactions are important for a secure and solid working of critical operations in enterprise applications. Several resources work in a transaction, for example, business components, databases, and services.

The next image shows a simple concept of a transaction. A transaction consists of three main operations: begin, commit, and rollback. The transaction is started by the begin operation. A series of steps is performed, and if all succeeds in the end, the commit operation is executed. The transaction must be rolled back through the rollback operation if some error occurs.

For example, we want to move money from our checking account to our savings account. Consider two operations: an operation to put off the money from the checking account and another operation to add the money to the savings account. Both the operations have to either fail together or succeed together. Credit and debit operations must work together in the same transaction. So for this transaction, the following operations must be executed:

  • Begin
  • Debit the checking account
  • Credit the savings account
  • Commit if successful and roll back in case of failure

Therefore, it's important that the entire transaction either succeeds or fails as a single piece. Without the transaction, the success or failure of just one operation in this transaction based on two operations will leave the system and the accounts in a very inconsistent state. The application cannot be used if the transactions are not correctly implemented.

Transactions have evolved over the years, always becoming simpler to use. JTA 1.2 introduces a very innovative annotation to make beans transactional. In Java EE 7, JTA 1.2 and JCA 1.7 are a very good couple for managing transactions. JTA lets us start a transaction; it provides us the begin, commit and rollback methods. JCA lets us propagate them inside the resources. For example, when an error is thrown in a database or some other external system, it must advice the JTA transaction to throw rollback. This is done through the resource adapter implementing the JCA specifications. Now, let's look at some examples of transactions working together in a H2 database. On returning to the banking transaction, we will obtain an account entity:

@Entity
public class Account {
@Id
private int number;
private double credit;

public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public double getCredit() {
return credit;
}
public void setCredit(double credit) {
this.credit = credit;
}
public void add(double credit) {
this.credit += credit;
}
public void less(double credit) throws Exception {
if (credit > this.credit)
throw new Exception();
this.credit -= credit;
}
}

We will also obtain the Bank bean that manages the accounts:

public class Bank {
@PersistenceContext
private EntityManager entityManager;

public void move(int accountToTake, int accountToPut, double amount) throws Exception {
Account from = entityManager.find(Account.class, accountToTake);
Account to = entityManager.find(Account.class, accountToPut);
from.less(amount);
to.add(amount);
entityManager.merge(from);
entityManager.merge(to);
}
}

This lets you move an amount between the two accounts. The first example represents the Bank as a stateless EJB:

@Stateless
public class PoorBank extends Bank {
}

In our database, let us assume that we have these two accounts:

INSERT INTO ACCOUNT(NUMBER, CREDIT) VALUES (123, 5555.87);
INSERT INTO ACCOUNT(NUMBER, CREDIT) VALUES (345, 2555.87);

Now, let us execute the move of the amount. Inject the stateless, as follows:

@EJB
private PoorBank poorBank;

Now, let's execute the move operation of 566.9 $ between the accounts 123 and 345:

poorBank.move(123, 345, 566.9);

Everything is okay. The amount from account 123 is reduced by 566.9 $ to 4988.97 $ and the amount in account 345 is increased to 3122.77 $. Now, use these two new accounts:

INSERT INTO ACCOUNT(NUMBER, CREDIT) VALUES (1231, 5555.87);
INSERT INTO ACCOUNT(NUMBER, CREDIT) VALUES (3451, 2555.87);

Now, try to execute a wrong operation; for example, try to move an amount greater than the current amount:

poorBank.move(1231, 3451, 20000);

As a result, we will see that the amount in the account 1231 is not reduced by 20000 $ and will remain 5555.87 $; however, the account 3451 is increased by 20000 $ to 22555.87 $. This is a bug for the bank and it risks the default!

..................Content has been hidden....................

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