190 likes | 321 Views
EclipseLink JPA Black Belt Course. Section 6: Transactions <PRESENTER>. EclipseLink JPA - Transactions. JTA versus RESOURCE_LOCAL Locking Optimistic Policies Pessimistic New Entities - PERSIST Detached Entities – MERGE Removing Entities - REMOVE. J2EE App. Transactions: Writing.
E N D
EclipseLink JPABlack Belt Course Section 6: Transactions <PRESENTER>
EclipseLink JPA - Transactions • JTA versus RESOURCE_LOCAL • Locking • Optimistic Policies • Pessimistic • New Entities - PERSIST • Detached Entities – MERGE • Removing Entities - REMOVE
J2EE App Transactions: Writing • J2EE apps typically support many clients sharing small number of db connections • Ideally would like to minimize length of transaction on database Begin Txn Time Begin Txn Commit Txn Commit Txn
Transactions: Minimal Writes • Persistence layer tracks/calculates changes • Only UPDATE modified columns • Order UPDATE, INSERT, & DELETES using referential integrity rules and consistent order • Benefits • Simplified development • Reduced TX costs • Minimize deadlock occurrences
Unit of Work • Unit of Work (UOW) provides object-level transaction functionality. • Implements Session API • Manages changes that are made to persistent objects • Commits these changes to the database as one atomic operation • If error occurs during UOW commit, then: • The database is rolled back • Changes that are made to all objects in the UOW are “rolled” back to their original state • At commit time, UOW: • Begins the database transaction • Performs minimal update to objects that have changed • Commits the transaction (if RESOURCE_LOCAL)
UOW Features • Transaction is created only at UOW commit time. • Results in short-running transactions • Updates only attributes that have changed • Rolls back both the objects and the database if something goes wrong during commit • A proper commit order is maintained by the UOW. Unit of Work is the preferred approach to committing changes to a database.
Unit of Work Basics oracle.toplink.sessions.UnitOfWork • Acquire a UOW. UnitOfWork uow = session.acquireUnitOfWork(); 2. Register objects requiring changes to the UOW. • Returns a “working copy” Person pCopy = (Person)uow.registerObject(person); • Apply changes to working copy • The UOW only tracks changes that are made to the working copy. pCopy.setFirstName(“Joan”); 4. Commit the UOW to permanently apply changes. uow.commit();
Object Registration in UOW • Registration creates a “working copy.” • Working copies of related objects are also created. • Related objects that are obtained from the working copy do not need to be registered. • The UOW tracks changes that are made in the working copy. • Commit: • Working copies are compared with “backup” copies. • Changes are committed to the database. • Post commit: • Changes that are made in the working copy are merged into the original object in the cache. • UOW and working copies can no longer be used.
Sequence of Events Unit of Work Commit Merge Registered persistent objects Edited clones Insert/update Relational Database (schema)
Unit of Work Example // Acquire UOW from a database session UnitOfWork uow = getSession().acquireUnitOfWork(); // Read an object Employee employeeOriginal = (Employee)getSession().readObject(Employee.class); // Register object -- a working copy is returned Employee employeeWorkingCopy = (Employee)uow.registerObject(employeeOriginal); // Update working copy employeeWorkingCopy.setFirstName("Geoff"); // commit; transaction created and SQL executed uow.commit(); UPDATE EMPLOYEE SET F_NAME = 'Geoff' WHERE (EMP_ID = 8) SQL optimized to only update what has changed
Unit of Work API • registerObject(Object), registerAllObjects(Vector) • Implicit if the UOW is used to perform the query: • commit() • Changes to clones are committed to the database. • Clones can no longer be used and should be thrown away. • commitAndResume() • Changes to clones are committed to the database, but these clones can still be used for further changes. // Using UOW will read & register in one step Employee employeeWorkingCopy = (Employee)uow.readObject(Employee.class);
Working with New Objects • Approach: 1. Register the new object with the UOW. 2. Make changes to the working copy. 3. Create the new object (do not set any attributes yet). • This is the preferred approach: • Unifying approach for most UOW scenarios • Still have a handle to the “original” object in the newP variable Person newP = new Person(); Person pCopy = (Person)uow.registerObject(newP); pCopy.setFirstName(”Paul"); pCopy.setLastName(“White”); uow.commit();
Working with New Objects • Alternative approach: • Create the new object, and populate attributes. • Register the new object with registerNewObject(). • registerNewObject() converts newP into the “working copy.” • After commit, newP does not hold on to the new object that is registered in cache. • Holds onto the working copy, which can no longer be used Person newP = new Person(); newP.setFirstName(”Paul"); newP.setLastName(“White”); uow.registerNewObject(newP); uow.commit(); newP == (Person)session.readObject(newP); false
Working with Relationships • Unifying approach: • Register both the source object and the target object. This returns working copies for each side of the relationship. • Make changes to working copies, if necessary. • Associate working copies with working copies. • You cannot associate an existing working copy with the existing original object and vice versa. Person p = (Person)session.readObject(Person.class); Address a = (Address)session.readObject(Address.class); Person pCopy = (Person)uow.registerObject(p); Address aCopy = (Address)uow.registerObject(a); pCopy.setAddress(aCopy); uow.commit();
Working with Relationships • Associating a new object to an existing object: 1. Register the existing object. 2. Create and register the new object, then populate. 3. Associate the two working copies. Person p = (Person)session.readObject(Person.class); Person pCopy = (Person)uow.registerObject(p); // create and populate new address AddressnewAddress=new Address(); Address aCopy = (Address) uow.registerObject(newAddress); aCopy.setCity(“Detroit”); aCopy.setState(“MI”); pCopy.setAddress(aCopy); uow.commit();
Working with Relationships • Associating an existing object to a new object: • Create the new object and register it with the UOW, then populate. • Create a working copy of the related object. • Assign the related object working copy to the new object working copy. Address aCopy = (Address)uow.readObject(Address.class); Person newP = new Person(); Person pCopy = (Person) uow.registerObject(newP); pCopy.setFirstName(“Will”); pCopy.setLastName(“Smith”); pCopy.setAddress(aCopy); uow.commit();
Concurrency Protection: Locking • Prevent data corruption !!! • Java Developers think of locking at the object level • Databases may need to manage locking across many applications • TopLink is able to respect and participate in locks at database level • Optimistic: Numeric, Timestamp, All fields, Selected fields, Changed field • Pessimistic
Transaction Features and Support • UnitOfWork provides Java abstraction • Minimizes database interactions • Calculates the minimal change set at commit time (deferred write) • Only the minimal DML issued • Respect database integrity • Orders INSERT, UPDATE and DELETE statements • “Unit Of Work” fully supports JTA
Transactions and the Cache • Client • Acquire UnitOfWork • Make Changes (Read, Update, Delete) • Commit (direct or JTA) • UnitOfWork • Write Changes • Calculate minimal changes • Order SQL statements • Execute statements • Cache Merge: Post TX commit • Merge in Shared/Isolated cache • Send change-set to other nodes if using coordination