001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.transaction.file;
018
019import java.io.InputStream;
020import java.io.OutputStream;
021
022import javax.transaction.Status;
023
024/**
025 * Interface for resource managers.
026 * 
027 * A resource manager is an entity
028 * that manages the processing and administration of resources.
029 * 
030 * What is specified here are methods
031 * <ul> 
032 * <li>for tasks related to starting and stopping of the resource manager
033 * <li>for transaction management, like
034 * starting, rolling back and committing of transactions  
035 * <li>to set and get transaction timeouts
036 * <li>to set the isolation level of a transaction
037 * <li>for the general administration of resources
038 * <li>for reading and writing of resources
039 * </ul> 
040 *  
041 * @version $Id: ResourceManager.java 513490 2007-03-01 20:46:28Z ozeigermann $
042 */
043public interface ResourceManager extends Status {
044
045    /**
046     * Isolation level <b>read uncommitted</b>: data written by other transactions can be read even before they commit  
047     */
048    public final static int ISOLATION_LEVEL_READ_UNCOMMITTED = 0;
049
050    /**
051     * Isolation level <b>read committed</b>: data written by other transactions can be read after they commit
052     */
053    public final static int ISOLATION_LEVEL_READ_COMMITTED = 10;
054
055    /**
056     * Isolation level <b>repeatable read</b>: data written by other transactions can be read after they commit if this transaction has not read this data before  
057     */
058    public final static int ISOLATION_LEVEL_REPEATABLE_READ = 50;
059
060    /**
061     * Isolation level <b>serializable</b>: result of other transactions will not influence the result of this transaction in any way
062     */
063    public final static int ISOLATION_LEVEL_SERIALIZABLE = 100;
064
065    /**
066     * Shutdown mode: Wait for all transactions to complete
067     */
068    public final static int SHUTDOWN_MODE_NORMAL = 0;
069
070    /**
071     * Shutdown mode: Try to roll back all active transactions
072     */
073    public final static int SHUTDOWN_MODE_ROLLBACK = 1;
074
075    /**
076     * Shutdown mode: Try to stop active transaction <em>NOW</em>, do no rollbacks
077     */
078    public final static int SHUTDOWN_MODE_KILL = 2;
079
080    /**
081     * Prepare result: resource manager guarantees a successful commit
082     */
083    public final static int PREPARE_SUCCESS = 1;
084
085    /**
086     * Prepare result: resource manager guarantees a successful commit as there is nothing to commit
087     */
088    public final static int PREPARE_SUCCESS_READONLY = 2;
089
090    /**
091     * Prepare result: transaction can not commit
092     */
093    public final static int PREPARE_FAILURE = -1;
094
095    /**
096     * Starts this resource manager. A resource manager must be started before transactions
097     * can be started or any operations on transactions can be executed.
098     * 
099     * @throws ResourceManagerSystemException if start failed due to internal problems
100     */
101    public void start() throws ResourceManagerSystemException;
102
103    /**
104     * Tries to stop this resource manager within the given timeout.
105     * 
106     * @param mode one of {@link #SHUTDOWN_MODE_NORMAL}, {@link #SHUTDOWN_MODE_ROLLBACK}  or {@link #SHUTDOWN_MODE_KILL}
107     * @param timeoutMSecs timeout for shutdown in milliseconds
108     * @return <code>true</code> if resource manager stopped within given timeout
109     * @throws ResourceManagerSystemException if something fatal hapened during shutdown
110     */
111    public boolean stop(int mode, long timeoutMSecs) throws ResourceManagerSystemException;
112
113    /**
114     * Tries to stop this resource manager within a default timeout.
115     * 
116     * @param mode one of predefined shutdown modes {@link #SHUTDOWN_MODE_NORMAL}, {@link #SHUTDOWN_MODE_ROLLBACK}  or {@link #SHUTDOWN_MODE_KILL}
117     * or any other int representing a shutdown mode
118     * @return <code>true</code> if resource manager stopped within given timeout
119     * @throws ResourceManagerSystemException if anything fatal hapened during shutdown
120     */
121    public boolean stop(int mode) throws ResourceManagerSystemException;
122
123    /**
124     * Tries to bring this resource manager back to a consistent state. 
125     * Might be called after system failure. An administrator might be forced
126     * to fix system errors outside this resource manager to actually make
127     * recovery possible. E.g. there may be a need for more disk space or
128     * a network connection must be reestablished.
129     * 
130     * @return <code>true</code> upon successful recovery of the resource manager
131     * @throws ResourceManagerSystemException if anything fatal hapened during recovery
132     */
133    public boolean recover() throws ResourceManagerSystemException;
134
135    /**
136     * Gets the default isolation level as an integer. 
137     * The higher the value the higher the isolation.
138     *  
139     * @return one of the predefined isolation levels {@link #ISOLATION_LEVEL_READ_UNCOMMITTED}, 
140     * {@link #ISOLATION_LEVEL_READ_COMMITTED}, {@link #ISOLATION_LEVEL_REPEATABLE_READ} or {@link #ISOLATION_LEVEL_SERIALIZABLE} 
141     * or any other int representing an isolation level
142     * @throws ResourceManagerException if an error occured
143     */
144    public int getDefaultIsolationLevel() throws ResourceManagerException;
145
146    /**
147     * Gets an array of all isolation levels supported by this resource manager.
148     * This array must not be <code>null</code> or empty as every resource manager has some sort of isolation level.
149     * 
150     * @return array of the predefined isolation levels {@link #ISOLATION_LEVEL_READ_UNCOMMITTED}, 
151     * {@link #ISOLATION_LEVEL_READ_COMMITTED}, {@link #ISOLATION_LEVEL_REPEATABLE_READ} or {@link #ISOLATION_LEVEL_SERIALIZABLE} 
152     * or any other int representing an isolation level
153     * @throws ResourceManagerException if an error occured
154     * @see #getDefaultIsolationLevel
155     */
156    public int[] getSupportedIsolationLevels() throws ResourceManagerException;
157
158    /**
159     * Tests if the specified isolation level is supported by this resource manager.
160     * 
161     * @param level isolation level whose support is to be tested 
162     * @return <code>true</code> if the isolation level is supported
163     * @throws ResourceManagerException if an error occured
164     * @see #getDefaultIsolationLevel
165     */
166    public boolean isIsolationLevelSupported(int level) throws ResourceManagerException;
167
168    /**
169     * Gets the isolation level for the specified transaction. 
170     * 
171     * @param txId identifier for the concerned transaction
172     * @return one of the predefined isolation levels {@link #ISOLATION_LEVEL_READ_UNCOMMITTED}, 
173     * {@link #ISOLATION_LEVEL_READ_COMMITTED}, {@link #ISOLATION_LEVEL_REPEATABLE_READ} or {@link #ISOLATION_LEVEL_SERIALIZABLE} 
174     * or any other int representing an isolation level
175     * @throws ResourceManagerException if an error occured
176     * @see #getDefaultIsolationLevel
177     */
178    public int getIsolationLevel(Object txId) throws ResourceManagerException;
179
180    /**
181     * Sets the isolation level for the specified transaction.
182     * <br>
183     * <em>Caution</em>: Implementations are likely to forbid changing the isolation level after any operations
184     * have been executed inside the specified transaction.  
185     * 
186     * @param txId identifier for the concerned transaction
187     * @param level one of the predefined isolation levels {@link #ISOLATION_LEVEL_READ_UNCOMMITTED}, 
188     * {@link #ISOLATION_LEVEL_READ_COMMITTED}, {@link #ISOLATION_LEVEL_REPEATABLE_READ} or {@link #ISOLATION_LEVEL_SERIALIZABLE} 
189     * or any other int representing an isolation level
190     * @throws ResourceManagerException if an error occured
191     * @see #getDefaultIsolationLevel
192     */
193    public void setIsolationLevel(Object txId, int level) throws ResourceManagerException;
194
195    /**
196     * Gets the default transaction timeout in milliseconds.
197     * After this time expires and the concerned transaction has not finished
198     * - either rolled back or committed - the resource manager is allowed and
199     * also encouraged - but not required - to abort the transaction and to roll it back.
200     * 
201     * @return default transaction timeout in milliseconds
202     * @throws ResourceManagerException if an error occured
203     */
204    public long getDefaultTransactionTimeout() throws ResourceManagerException;
205
206    /**
207     * Gets the transaction timeout of the specified transaction in milliseconds.
208     * 
209     * @param txId identifier for the concerned transaction
210     * @return transaction timeout of the specified transaction in milliseconds
211     * @throws ResourceManagerException if an error occured
212     * @see #getDefaultTransactionTimeout
213     */
214    public long getTransactionTimeout(Object txId) throws ResourceManagerException;
215
216    /**
217     * Sets the transaction timeout of the specified transaction in milliseconds.
218     * 
219     * @param txId identifier for the concerned transaction
220     * @param mSecs transaction timeout of the specified transaction in milliseconds
221     * @throws ResourceManagerException if an error occured
222     * @see #getDefaultTransactionTimeout
223     */
224    public void setTransactionTimeout(Object txId, long mSecs) throws ResourceManagerException;
225
226    /**
227     * Creates and starts a transaction using the specified transaction identifier.
228     * The identifier needs to be unique to this resource manager.
229     * As there is no transaction object returned all access to the transaction
230     * needs to be addressed to this resource manager.
231     * 
232     * @param txId identifier for the transaction to be started
233     * @throws ResourceManagerException if an error occured
234     */
235    public void startTransaction(Object txId) throws ResourceManagerException;
236
237    /**
238     * Prepares the transaction specified by the given transaction identifier for commit.
239     * The preparation may either succeed ({@link #PREPARE_SUCCESS}), 
240     * succeed as there is nothing to commit ({@link #PREPARE_SUCCESS_READONLY})
241     * or fail ({@link #PREPARE_FAILURE}). If the preparation fails, commit will
242     * fail as well and the transaction should be marked for rollback. However, if it 
243     * succeeds the resource manager must guarantee that a following commit will succeed as well.
244     * 
245     * <br><br>
246     * An alternative way to singal a <em>failed</em> status is to throw an exception.
247     * 
248     * @param txId identifier for the transaction to be prepared
249     * @return result of the preparation effort, either {@link #PREPARE_SUCCESS}, {@link #PREPARE_SUCCESS_READONLY} or {@link #PREPARE_FAILURE}   
250     * @throws ResourceManagerException alternative way to signal prepare failed
251     */
252    public int prepareTransaction(Object txId) throws ResourceManagerException;
253
254    /**
255     * Marks the transaction specified by the given transaction identifier for rollback.
256     * This means, even though the transaction is not actually finished, no other operation
257     * than <code>rollback</code> is permitted.
258     * 
259     * @param txId identifier for the transaction to be marked for rollback
260     * @throws ResourceManagerException if an error occured
261     */
262    public void markTransactionForRollback(Object txId) throws ResourceManagerException;
263
264    /**
265     * Rolls back the transaction specified by the given transaction identifier. 
266     * After roll back the resource manager is allowed to forget about
267     * the associated transaction.
268     * 
269     * @param txId identifier for the transaction to be rolled back
270     * @throws ResourceManagerException if an error occured
271     */
272    public void rollbackTransaction(Object txId) throws ResourceManagerException;
273
274    /**
275     * Commis the transaction specified by the given transaction identifier. 
276     * After commit the resource manager is allowed to forget about
277     * the associated transaction.
278     * 
279     * @param txId identifier for the transaction to be committed
280     * @throws ResourceManagerException if an error occured
281     */
282    public void commitTransaction(Object txId) throws ResourceManagerException;
283
284    /**
285     * Gets the state of the transaction specified by the given transaction identifier.
286     * The state will be expressed by an <code>int</code> code as defined 
287     * in the {@link javax.transaction.Status} interface. 
288     * 
289     * @param txId identifier for the transaction for which the state is returned
290     * @return state of the transaction as defined in {@link javax.transaction.Status}
291     * @throws ResourceManagerException if an error occured
292     */
293    public int getTransactionState(Object txId) throws ResourceManagerException;
294
295    /**
296     * Explicitly locks a resource. Although locking must be done implicitly by methods 
297     * creating, reading or modifying resources, there may be cases when you want to do this
298     * explicitly.<br>
299     * 
300     *<br>
301     * <em>Note</em>: By intention the order of parameters (<code>txId</code> does not come first) is different than in other methods of this interface. 
302     * This is done to make clear locking affects all transactions, not only the locking one. 
303     * This should be clear anyhow, but seems to be worth noting.
304     * 
305     * @param resourceId identifier for the resource to be locked 
306     * @param txId identifier for the transaction that tries to acquire a lock
307     * @param shared <code>true</code> if this lock may be shared by other <em>shared</em> locks
308     * @param wait <code>true</code> if the method shall block when lock can not be acquired now
309     * @param timeoutMSecs timeout in milliseconds
310     * @param reentrant <code>true</code> if the lock should be acquired even when the <em>requesting transaction and no other</em> holds an incompatible lock
311     * @return <code>true</code> when the lock has been acquired
312     * @throws ResourceManagerException if an error occured
313     */
314    public boolean lockResource(
315        Object resourceId,
316        Object txId,
317        boolean shared,
318        boolean wait,
319        long timeoutMSecs,
320        boolean reentrant)
321        throws ResourceManagerException;
322
323    /**
324     * Explicitly locks a resource in reentrant style. This method blocks until the lock
325     * actually can be acquired or the transaction times out. 
326     * 
327     * @param resourceId identifier for the resource to be locked 
328     * @param txId identifier for the transaction that tries to acquire a lock
329     * @param shared <code>true</code> if this lock may be shared by other <em>shared</em> locks
330     * @throws ResourceManagerException if an error occured
331     * @see #lockResource(Object, Object, boolean, boolean, long, boolean)
332     */
333    public boolean lockResource(Object resourceId, Object txId, boolean shared) throws ResourceManagerException;
334
335    /**
336     * Explicitly locks a resource exclusively, i.e. for writing, in reentrant style. This method blocks until the lock
337     * actually can be acquired or the transaction times out. 
338     * 
339     * @param resourceId identifier for the resource to be locked 
340     * @param txId identifier for the transaction that tries to acquire a lock
341     * @throws ResourceManagerException if an error occured
342     * @see #lockResource(Object, Object, boolean)
343     * @see #lockResource(Object, Object, boolean, boolean, long, boolean)
344     */
345    public boolean lockResource(Object resourceId, Object txId) throws ResourceManagerException;
346
347    /**
348     * Checks if a resource exists. 
349     * 
350     * @param txId identifier for the transaction in which the resource is to be checked for
351     * @param resourceId identifier for the resource to check for 
352     * @return <code>true</code> if the resource exists
353     * @throws ResourceManagerException if an error occured
354     */
355    public boolean resourceExists(Object txId, Object resourceId) throws ResourceManagerException;
356
357    /**
358     * Checks if a resource exists wihtout being in a transaction. This means only take
359     * into account resources already globally commited.
360     * 
361     * @param resourceId identifier for the resource to check for 
362     * @return <code>true</code> if the resource exists
363     * @throws ResourceManagerException if an error occured
364     */
365    public boolean resourceExists(Object resourceId) throws ResourceManagerException;
366
367    /**
368     * Deletes a resource.
369     * 
370     * @param txId identifier for the transaction in which the resource is to be deleted
371     * @param resourceId identifier for the resource to be deleted
372     * @throws ResourceManagerException if the resource does not exist or any other error occured
373     */
374    public void deleteResource(Object txId, Object resourceId) throws ResourceManagerException;
375
376    /**
377     * Deletes a resource.
378     * 
379     * @param txId identifier for the transaction in which the resource is to be deleted
380     * @param resourceId identifier for the resource to be deleted
381     * @param assureOnly if set to <code>true</code> this method will not throw an exception when the resource does not exist
382     * @throws ResourceManagerException if the resource does not exist and <code>assureOnly</code> was not set to <code>true</code> or any other error occured
383     */
384    public void deleteResource(Object txId, Object resourceId, boolean assureOnly) throws ResourceManagerException;
385
386    /**
387     * Creates a resource.
388     * 
389     * @param txId identifier for the transaction in which the resource is to be created
390     * @param resourceId identifier for the resource to be created
391     * @throws ResourceManagerException if the resource already exist or any other error occured
392     */
393    public void createResource(Object txId, Object resourceId) throws ResourceManagerException;
394
395    /**
396     * Creates a resource.
397     * 
398     * @param txId identifier for the transaction in which the resource is to be created
399     * @param resourceId identifier for the resource to be created
400     * @param assureOnly if set to <code>true</code> this method will not throw an exception when the resource already exists
401     * @throws ResourceManagerException if the resource already exists and <code>assureOnly</code> was not set to <code>true</code> or any other error occured
402     */
403    public void createResource(Object txId, Object resourceId, boolean assureOnly) throws ResourceManagerException;
404    
405        /**
406         * Opens a streamable resource for reading.
407         * 
408         * <br><br>
409         * <em>Important</em>: By contract, the application is responsible for closing the stream after its work is finished.
410         * 
411         * @param txId identifier for the transaction in which the streamable resource is to be openend
412         * @param resourceId identifier for the streamable resource to be opened
413         * @return stream to read from 
414         * @throws ResourceManagerException if the resource does not exist or any other error occured
415         */
416        public InputStream readResource(Object txId, Object resourceId) throws ResourceManagerException;
417    
418        /**
419         * Opens a streamable resource for a single reading request not inside the scope of a transaction.
420         *  
421         * <br><br>
422         * <em>Important</em>: By contract, the application is responsible for closing the stream after its work is finished.
423         * 
424         * @param resourceId identifier for the streamable resource to be opened
425         * @return stream to read from 
426         * @throws ResourceManagerException if the resource does not exist or any other error occured
427         */
428        public InputStream readResource(Object resourceId) throws ResourceManagerException;
429
430        /**
431         * Opens a resource for writing. 
432         * 
433         * <br><br>
434         * <em>Important</em>: By contract, the application is responsible for closing the stream after its work is finished.
435         * 
436         * @param txId identifier for the transaction in which the streamable resource is to be openend
437         * @param resourceId identifier for the streamable resource to be opened
438         * @return stream to write to 
439         * @throws ResourceManagerException if the resource does not exist or any other error occured
440         */
441        public OutputStream writeResource(Object txId, Object resourceId) throws ResourceManagerException;
442}