summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/Repository.java
blob: d9d1212593b72e48b95a72cd02ab7b0c8fae308a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
 * Copyright 2006-2012 Amazon Technologies, Inc. or its affiliates.
 * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
 * of Amazon Technologies, Inc. or its affiliates.  All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.amazon.carbonado;

import com.amazon.carbonado.capability.Capability;

/**
 * A Repository represents a database for {@link Storable}
 * instances. Some repositories do not have control over the schema (for example, a JDBC
 * Repository depends on the schema defined by the underlying relational database); such
 * repositories are called "dependent".  Conversely, a repository which has complete control
 * over the schema is termed "independent".
 *
 * <P>A dependent repository requires and will verify that Storables
 * have a matching definition in the external storage layer. An independent
 * repository will automatically update type definitions in its database to
 * match changes to Storable definitions.
 *
 * <p>Repository instances should be thread-safe and immutable. Therefore, it
 * is safe for multiple threads to be interacting with a Repository.
 *
 * @author Brian S O'Neill
 * @see RepositoryBuilder
 */
public interface Repository {
    /**
     * Returns the name of this repository.
     */
    String getName();

    /**
     * Returns a Storage instance for the given user defined Storable class or
     * interface.
     *
     * @return specific type of Storage instance
     * @throws IllegalArgumentException if specified type is null
     * @throws MalformedTypeException if specified type is not suitable
     * @throws SupportException if specified type cannot be supported
     * @throws RepositoryException if storage layer throws any other kind of
     * exception
     */
    <S extends Storable> Storage<S> storageFor(Class<S> type)
        throws SupportException, RepositoryException;

    /**
     * Causes the current thread to enter a transaction scope. Call commit
     * inside the transaction in order for any updates to the repository to be
     * applied. Be sure to call exit when leaving the scope.
     * <p>
     * To ensure exit is called, use transactions as follows:
     * <pre>
     * Transaction txn = repository.enterTransaction();
     * try {
     *     // Make updates to storage layer
     *     ...
     *
     *     // Commit the changes up to this point
     *     txn.commit();
     *
     *     // Optionally make more updates
     *     ...
     *
     *     // Commit remaining changes
     *     txn.commit();
     * } finally {
     *     // Ensure transaction exits, aborting uncommitted changes if an exception was thrown
     *     txn.exit();
     * }
     * </pre>
     */
    Transaction enterTransaction();

    /**
     * Causes the current thread to enter a transaction scope with an explict
     * isolation level. The actual isolation level may be higher than
     * requested, if the repository does not support the exact level. If the
     * repository does not support a high enough level, it throws an
     * UnsupportedOperationException.
     *
     * @param level minimum desired transaction isolation level -- if null, a
     * suitable default is selected
     * @see #enterTransaction()
     * @throws UnsupportedOperationException if repository does not support
     * isolation as high as the desired level
     */
    Transaction enterTransaction(IsolationLevel level);

    /**
     * Causes the current thread to enter a <i>top-level</i> transaction scope
     * with an explict isolation level. The actual isolation level may be
     * higher than requested, if the repository does not support the exact
     * level. If the repository does not support a high enough level, it throws
     * an UnsupportedOperationException.
     *
     * <p>This method requests a top-level transaction, which means it never
     * has a parent transaction, but it still can be a parent transaction
     * itself. This kind of transaction is useful when a commit must absolutely
     * succeed, even if the current thread is already in a transaction
     * scope. If there was a parent transaction, then a commit might still be
     * rolled back by the parent.
     *
     * <p>Requesting a top-level transaction can be deadlock prone if the
     * current thread is already in a transaction scope. The top-level
     * transaction may not be able to obtain locks held by the parent
     * transaction. An alternative to requesting top-level transactions is to
     * execute transactions in separate threads.
     *
     * @param level minimum desired transaction isolation level -- if null, a
     * suitable default is selected
     * @see #enterTransaction()
     * @throws UnsupportedOperationException if repository does not support
     * isolation as high as the desired level
     */
    Transaction enterTopTransaction(IsolationLevel level);

    /**
     * Returns the isolation level of the current transaction, or null if there
     * is no transaction in the current thread.
     */
    IsolationLevel getTransactionIsolationLevel();

    /**
     * Requests a specific capability of this Repository. This allows
     * repositories to support extended features without having to clutter the
     * main repository interface. The list of supported capabilities is
     * documented with repository implementations.
     *
     * @param capabilityType type of capability requested
     * @return capability instance or null if not supported
     */
    <C extends Capability> C getCapability(Class<C> capabilityType);

    /**
     * Closes this repository reference, aborting any current
     * transactions. Operations on objects returned by this repository will
     * fail when accessing the storage layer.
     *
     * @throws SecurityException if caller does not have permission
     */
    void close();

    /**
     * Returns true if repository was explicitly closed or shutdown.
     */
    //boolean isClosed();
}