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     */
017    package org.apache.commons.transaction.file;
018    
019    import java.io.InputStream;
020    import java.io.OutputStream;
021    
022    import 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     */
043    public 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    }