The technique in section applies only to the EJB 2.1 architecture. In the EJB 3.0 architecture, use the Java Persistence API (JPA).
Use version consistency to improve performance while protecting the integrity of data in the database. Since the application server can use multiple copies of an EJB component simultaneously, an EJB component’s state can potentially become corrupted through simultaneous access.
The standard way of preventing corruption is to lock the database row associated with a particular bean. This prevents the bean from being accessed by two simultaneous transactions and thus protects data. However, it also decreases performance, since it effectively serializes all EJB access.
Version consistency is another approach to protecting EJB data integrity. To use version consistency, you specify a column in the database to use as a version number. The EJB lifecycle then proceeds like this:
The first time the bean is used, the ejbLoad() method loads the bean as normal, including loading the version number from the database.
The ejbStore() method checks the version number in the database versus its value when the EJB component was loaded.
If the version number has been modified, it means that there has been simultaneous access to the EJB component and ejbStore() throws a ConcurrentModificationException.
Otherwise, ejbStore() stores the data and completes as normal.
The ejbStore() method performs this validation at the end of the transaction regardless of whether any data in the bean was modified.
Subsequent uses of the bean behave similarly, except that the ejbLoad() method loads its initial data (including the version number) from an internal cache. This saves a trip to the database. When the ejbStore() method is called, the version number is checked to ensure that the correct data was used in the transaction.
Version consistency is advantageous when you have EJB components that are rarely modified, because it allows two transactions to use the same EJB component at the same time. Because neither transaction modifies the data, the version number is unchanged at the end of both transactions, and both succeed. But now the transactions can run in parallel. If two transactions occasionally modify the same EJB component, one will succeed and one will fail and can be retried using the new values—which can still be faster than serializing all access to the EJB component if the retries are infrequent enough (though now your application logic has to be prepared to perform the retry operation).
To use version consistency, the database schema for a particular table must include a column where the version can be stored. You then specify that table in the sun-cmp-mapping.xml deployment descriptor for a particular bean:
<entity-mapping> <cmp-field-mapping> ... </cmp-field-mapping> <consistency> <check-version-of-accessed-instances> <column-name>OrderTable.VC_VERSION_NUMBER</column-name> </check-version-of-accessed-instances> </consistency> </entity-mapping>
In addition, you must establish a trigger on the database to automatically update the version column when data in the specified table is modified. The Application Server requires such a trigger to use version consistency. Having such a trigger also ensures that external applications that modify the EJB data will not conflict with EJB transactions in progress.
For example, the following DDL illustrates how to create a trigger for the Order table:
CREATE TRIGGER OrderTrigger BEFORE UPDATE ON OrderTable FOR EACH ROW WHEN (new.VC_VERSION_NUMBER = old.VC_VERSION_NUMBER) DECLARE BEGIN :NEW.VC_VERSION_NUMBER := :OLD.VC_VERSION_NUMBER + 1; END;