Savepoints allow for fine grained control over the transactional behavior of your application. Kodo's savepoint API allow you to set intermediate rollback points in your transaction. You can then choose to rollback changes made only after a specific savepoint, then commit or continue making new changes in the transaction. This feature is useful for multi-stage transactions, such as editing a set of objects over several web pages or user screens. Savepoints also provide more flexibilty to conditional transaction behavior, such as choosing to commit or rollback a portion of the transaction based on the results of the changes. This chapter describes how to use and configure Kodo savepoints.
		Kodo's
		
		
		KodoEntityManager 
		
		and
		
		
		KodoPersistenceManager
		
		have the following methods to control savepoint behavior.
		Note that the savepoints work in tandem with the current
		transaction.  This means that savepoints require an open transaction, 
		and that a rollback of the transaction will rollback all of 
		the changes in the transaction regardless of any savepoints set.
		
void setSavepoint (String name); void releaseSavepoint (String name); void rollbackToSavepoint (String name);
		To set a savepoint, simply call setSavepoint, 
		passing in a symbolic savepoint name.  
		This savepoint will define a point at which you can preserve
		the state of transactional objects for the duration of the current
		transaction.
		
		Having set a named savepoint, you can rollback changes made after that
		point by calling rollbackToSavepoint.  This 
		method will keep the current transaction active,
		while restoring all transactional instances back to their saved state.
		Instances that were deleted after the save point will no longer
		be marked for deletion.  Similarly, transient instances that were
		made persistent after the savepoint will become transient again.  
		Savepoints made after this savepoint will be released and no longer 
		valid, although you can still set new savepoints.  Savepoints will also
		be cleared after the current transaction is committed or rolled back.
		
		If a savepoint is no longer needed, you can release any resources
		such as in memory state and datastore resources by calling
		releaseSavepoint.
		This method should not be called for savepoints that have been 
		released automatically through other means, such as commit of a 
		transaction or rollback to a prior savepoint.  While savepoints
		made after this savepoint will also be released, there are no other
		effects on the current transaction.
		
The following simple example illustrates setting, releasing, and rolling back to a savepoint.
Example 9.8. Using Savepoints
JPA:
import kodo.persistence.*;
...
KodoEntityManager kem = KodoPersistence.cast (em);
kem.getTransaction ().begin ();
Magazine mag = kem.find (Magazine.class, id);
mag.setPageCount (300);
kem.setSavepoint ("pages");
mag.setPrice (mag.getPageCount () * pricePerPage);
// we decide to release pages since price depends on pages.
kem.releaseSavepoint ("pages");
kem.setSavepoint ("price");
mag.setPrice (testPrice);
...
// we determine the test price is not good
kem.rollbackToSavepoint ("price");
// the price is now restored to mag.getPageCount () * pricePerPage
kem.getTransaction ().commit ();
JDO:
import kodo.jdo.*;
...
KodoPersistenceManager kpm = KodoJDOHelper.cast (pm);
kpm.currentTransaction ().begin ();
Magazine mag = (Magazine) kpm.getObjectById (id, true);
mag.setPageCount (300);
kpm.setSavepoint ("pages");
mag.setPrice (mag.getPageCount () * pricePerPage);
// we decide to release pages since price depends on pages.
kpm.releaseSavepoint ("pages");
kpm.setSavepoint ("price");
mag.setPrice (testPrice);
...
// we determine the test price is not good
kpm.rollbackToSavepoint ("price");
// the price is now restored to mag.getPageCount () * pricePerPage
kpm.currentTransaction ().commit ();
		Kodo uses the 
		kodo.kernel.SavepointManager 
		plugin to handle
		perserving the savepoint state.  Kodo includes the following
		SavepointManager plugins:
		
				in-mem: The default.  This is an alias
				for the 
				kodo.kernel.InMemorySavepointManager
				.  This plugin stores all state, including field 
				values, in memory.  Due to this behavior, each set savepoint 
				is designed for small to medium transactional object counts.
				
				jdbc: This is an alias for the 
				kodo.jdbc.kernel.JDBCSavepointManager.
				This plugin requires JDBC 3 and 
				java.sql.Savepoint support to operate.  Note that 
				this plugin implements savepoints by issuing a flush to the 
				database.
				
				oracle: This is an alias for the 
				kodo.jdbc.sql.OracleSavepointManager.
				This plugin operates similarly to the JDBC
				plugin; however, it uses Oracle-specific calls.
				This plugin requires using the Oracle JDBC driver and database,
				versions 9.2 or higher.  Note that this 
				plugin implements savepoints by issuing a flush to the database.