001: /**
002: * Copyright (C) 2006, 2007 David Bulmore, Software Sensation Inc.
003: * All Rights Reserved.
004: *
005: * This file is part of JPersist.
006: *
007: * JPersist is free software; you can redistribute it and/or modify it under
008: * the terms of the GNU General Public License (Version 2) as published by
009: * the Free Software Foundation.
010: *
011: * JPersist is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with JPersist; if not, write to the Free Software Foundation,
018: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
019: */package jpersist;
020:
021: import java.sql.Savepoint;
022: import java.util.Set;
023:
024: /**
025: * Encloses multiple database calls in a single transaction. This class must
026: * be used with jpersist.PersistentObject.save(Transaction) calls to be
027: * effective and/or using the TransactionManager.getDatabase() to work
028: * with the database handler that is involved in the transaction.
029: * <p>An example of this is:
030: * <pre>
031: * new TransactionManager(dbm) {
032: * public void run() throws JPersistException
033: * {
034: * // Inserting individually
035: * new Contact("alincoln", ...).save(this);
036: * // and/or
037: * getDatabase().saveObject(new Order("alincoln", ...));
038: * // and/or
039: * saveObject(new Order("alincoln", ...));
040: * }
041: * }.executeTransaction();
042: * </pre>
043: * While the transaction manager handles beginning the transaction, ending the
044: * transaction, committing the transaction, and rolling back the transaction,
045: * it's still also possible to use save points, rollback, and commit at any
046: * point within.
047: */
048: public abstract class TransactionManager {
049: Database database;
050: boolean closeDatabase;
051:
052: /**
053: * This constructor takes a database manager.
054: *
055: * @param databaseManager a jpersist.DatabaseManager instance
056: */
057: public TransactionManager(DatabaseManager databaseManager)
058: throws JPersistException {
059: this .database = databaseManager.getDatabase();
060: closeDatabase = true;
061: }
062:
063: /**
064: * This constructor takes a database.
065: *
066: * @param database a jpersist.Database instance
067: */
068: public TransactionManager(Database database)
069: throws JPersistException {
070: this .database = database;
071: }
072:
073: /**
074: * Returns the database being used for the transaction. This is useable for
075: * any database functionality, including commits, Savepoints, and rollbacks.
076: */
077: public Database getDatabase() {
078: return database;
079: }
080:
081: /**
082: * Override this method with your own.
083: */
084: public abstract void run() throws Exception;
085:
086: /**
087: * Calls the jpersist.Database version.
088: */
089: public int saveObject(Object object) throws JPersistException {
090: return database.saveObject(object);
091: }
092:
093: /**
094: * Calls the jpersist.Database version.
095: */
096: public int saveObject(Object object, Set<String> nullValuesToInclude)
097: throws JPersistException {
098: return database.saveObject(object, nullValuesToInclude);
099: }
100:
101: /**
102: * Calls the jpersist.Database version.
103: */
104: public int saveObject(Object object, String externalClauses,
105: Object... externalClausesParameters)
106: throws JPersistException {
107: return database.saveObject(object, externalClauses,
108: externalClausesParameters);
109: }
110:
111: /**
112: * Calls the jpersist.Database version.
113: */
114: public int saveObject(Object object,
115: Set<String> nullValuesToInclude, String externalClauses,
116: Object... externalClausesParameters)
117: throws JPersistException {
118: return database.saveObject(object, nullValuesToInclude,
119: externalClauses, externalClausesParameters);
120: }
121:
122: /**
123: * Calls the jpersist.Database version.
124: */
125: public int deleteObject(Object object) throws JPersistException {
126: return database.deleteObject(object);
127: }
128:
129: /**
130: * Calls the jpersist.Database version.
131: */
132: public int deleteObject(Object object,
133: Set<String> nullValuesToInclude) throws JPersistException {
134: return database.deleteObject(object, nullValuesToInclude);
135: }
136:
137: /**
138: * Calls the jpersist.Database version.
139: */
140: public int deleteObject(Object object, String externalClauses,
141: Object... externalClausesParameters)
142: throws JPersistException {
143: return database.deleteObject(object, externalClauses,
144: externalClausesParameters);
145: }
146:
147: /**
148: * Calls the jpersist.Database version.
149: */
150: public int deleteObject(Object object,
151: Set<String> nullValuesToInclude, String externalClauses,
152: Object... externalClausesParameters)
153: throws JPersistException {
154: return database.deleteObject(object, nullValuesToInclude,
155: externalClauses, externalClausesParameters);
156: }
157:
158: /**
159: * Calls the jpersist.Database version.
160: */
161: public void commit() throws JPersistException {
162: database.commit();
163: }
164:
165: /**
166: * Calls the jpersist.Database version.
167: */
168: public void rollback() throws JPersistException {
169: database.rollback();
170: }
171:
172: /**
173: * Calls the jpersist.Database version.
174: */
175: public void rollback(Savepoint savepoint) throws JPersistException {
176: database.rollback(savepoint);
177: }
178:
179: /**
180: * Calls the jpersist.Database version.
181: */
182: public Savepoint setSavepoint() throws JPersistException {
183: return database.setSavepoint();
184: }
185:
186: /**
187: * Calls the jpersist.Database version.
188: */
189: public Savepoint setSavepoint(String name) throws JPersistException {
190: return database.setSavepoint(name);
191: }
192:
193: /**
194: * Calls the jpersist.MetaData version.
195: */
196: public boolean supportsSavepoints() throws JPersistException {
197: return database.getMetaData().supportsSavepoints();
198: }
199:
200: /**
201: * Call this method to execute the transaction (and the run() method). If no
202: * exceptions occur the transaction will be commited. Othwerwise, the
203: * transaction will be rolled back.
204: */
205: public void executeTransaction() throws JPersistException {
206: try {
207: database.beginTransaction();
208:
209: run();
210: } catch (Exception e) {
211: database.rollback();
212:
213: throw new JPersistException("Transaction was rolled back",
214: e);
215: } finally {
216: database.endTransaction();
217:
218: if (closeDatabase)
219: database.close();
220: }
221: }
222: }
|