|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface TransactionalEditingDomain
An extension of the EditingDomain
API that applies transactional
semantics to reading and writing the contents of an EMF ResourceSet
.
Editing domains can be created in one of two ways: dynamically, using
a TransactionalEditingDomain.Factory
or statically by registration on the
org.eclipse.emf.transaction.editingDomains
extension point.
The latter mechanism is the preferred way to define editing domains that
can be shared with other applications. To create a new editing domain in
code, simply invoke the static factory instance:
TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(); ResourceSet rset = domain.getResourceSet(); // or, create our own resource set and initialize the domain with it rset = new MyResourceSetImpl(); domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(rset);
To share a named editing domain with other applications, the editing domain registry can be used to obtain domains by ID, creating them if necessary. Editing domain IDs are configured on an extension point providing the factory implementation that the registry uses to initialize them:
<!-- In the plugin.xml --> <extension point="org.eclipse.emf.transaction.editingDomains"> <editingDomain id="com.example.MyEditingDomain" factory="com.example.MyEditingDomainFactory"/> </extension> // in code, access the registered editing domain by: TransactionalEditingDomain myDomain = TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain( "com.example.MyEditingDomain");
See the package documentation
for further
details of editing domain usage.
As of the EMF Transaction 1.2 release, editing domains may optionally be
Adaptable
to a variety of optional extension interfaces or "facets."
It is recommended to implement the Adaptable interface and support
adaptation to these interfaces to benefit from the services that they offer.
TransactionalCommandStack
,
Transaction
,
ResourceSetListener
Nested Class Summary | |
---|---|
static interface |
TransactionalEditingDomain.DefaultOptions
Adapter interface provided by TransactionalEditingDomain s that
support the notion of default transaction options. |
static interface |
TransactionalEditingDomain.Factory
Interface defining the protocol for creating transactional editing domains. |
static interface |
TransactionalEditingDomain.Registry
An ID-based registry of shareable TransactionalEditingDomain instances. |
Method Summary | |
---|---|
void |
addResourceSetListener(ResourceSetListener l)
Adds a resource set listener to me, to receive notifications of changes to the resource set when transactions commit. |
RunnableWithResult<?> |
createPrivilegedRunnable(Runnable runnable)
Wraps the specified runnable to give it access to the currently
active transaction. |
void |
dispose()
Disposes of this editing domain and any resources that it has allocated. |
String |
getID()
Obtains my unique ID. |
void |
removeResourceSetListener(ResourceSetListener l)
Removes a resource set listener from me. |
Object |
runExclusive(Runnable read)
Runs an operation that requires exclusive access to my resource set, for reading. |
void |
setID(String id)
Sets my unique ID. |
void |
yield()
Temporarily yields access to another read-only transaction. |
Methods inherited from interface org.eclipse.emf.edit.domain.EditingDomain |
---|
createCommand, createOverrideCommand, createResource, getChildren, getClipboard, getCommandStack, getNewChildDescriptors, getOptimizeCopy, getParent, getResourceSet, getRoot, getTreePath, isControllable, isReadOnly, loadResource, setClipboard, treeIterator |
Method Detail |
---|
String getID()
TransactionalEditingDomain.Registry
(if I am registered).
TransactionalEditingDomain.Registry.getEditingDomain(String)
void setID(String id)
TransactionalEditingDomain.Registry
,
then I am re-registered under this new ID. However, if I am registered
statically on the org.eclipse.emf.transaction.editingDomains
extension point, then my ID cannot be changed.
id
- my new unique identifier
IllegalArgumentException
- if I am a statically registered domaingetID()
,
TransactionalEditingDomain.Registry.add(String, TransactionalEditingDomain)
void addResourceSetListener(ResourceSetListener l)
l
- a new resource set listener
IllegalArgumentException
- if the listener declares both that it
wants only pre-commit events and that it wants only post-commit
events (a logical contradiction)ResourceSetListener.isPrecommitOnly()
,
ResourceSetListener.isPostcommitOnly()
void removeResourceSetListener(ResourceSetListener l)
l
- a resource set listener to removeObject runExclusive(Runnable read) throws InterruptedException
RunnableWithResult
interface, then its result is returned after it completes. Moreover,
(and this is a very good reason to implement this extension interface),
if the transaction rolls back on commit, then the RunnableWithResult
is provided with the error status indicating this condition. Even read-only
transactions can roll back when, for example, another thread concurrently
modifies the model (in violation of the transaction protocol), and it is
important to know when corrupted data may have been read.
Note that this method will block the current thread until exclusive access to the resource set can be obtained. However, it is safe to call this method on the Eclipse UI thread because special precaution is taken to ensure that liveness is maintained (using mechanisms built into the Job Manager).
Note: Since the 1.2 release, the
TransactionUtil.runExclusive(TransactionalEditingDomain, RunnableWithResult)
utility provides type-safe execution of runnables returning results and
should be preferred over this API.
read
- a read-only operation to execute
RunnableWithResult
and the transaction did not roll back;
null
, otherwise
InterruptedException
- if the current thread is interrupted while
waiting for access to the resource setTransactionUtil#runExclusive(RunnableWithResult)
,
Transaction.commit()
void yield()
TransactionalEditingDomain
supports any number of pseudo-concurrent
read-only transactions. Transactions that are expected to be
long-running should yield frequently, as a task running in a progress
monitor is expected to check for cancellation frequently. However, there
is a higher cost (in time) associated with yielding, so it should not
be overdone.
Only read-only transactions may yield, and only the transaction that is currently active in the editing domain may yield. The yielding transaction may be nested, but not within a read/write transaction at any depth.
Upon yielding, some other read-only transaction that is attempting to start or to return from a yield will take control of the editing domain. Control is never yielded to a read/write transaction (not even to a read-only transaction nested in a read/write) because this would introduce dirty reads (transactions reading uncommitted changes). If there are no other read-only transactions to receive the transfer of control, then the call returns immediately. Otherwise, control is transferred in FIFO fashion to waiting transactions.
RunnableWithResult<?> createPrivilegedRunnable(Runnable runnable)
runnable
to give it access to the currently
active transaction. This is useful for two or more cooperating threads
to share a transaction (read-only or read-write), executing code in
the a runnable
on one thread in the context of another
thread's transaction.
For example, in an Eclipse UI application, this might be used when a long-running task in a modal context thread needs to synchronously execute some operation on the UI thread, which operation needs to read or write the editing domain. e.g.,
Runnable uiBoundAction = // ... Runnable privileged = domain.createPrivilegedRunnable(uiBoundAction); Display.syncExec(privileged);
Note that it is critically important that this mechanism only be used to share a transaction with another thread synchronously. Or, more generally, during the execution of the privileged runnable, the thread that originally owned the transaction no longer does, and may not access the editing domain. Upon completion of the privileged runnable, the transaction is returned to its original owner.
Also, the resulting runnable may only be executed while the currently
active transaction remains active. Any attempt to execute the runnable
after this transaction has committed or while a nested transaction is
active will result in an IllegalStateException
.
Note: Since the 1.2 release, the
TransactionUtil.createPrivilegedRunnable(TransactionalEditingDomain, RunnableWithResult)
utility provides type-safe privileged access for runnables returning
results and should be preferred over this API.
T
- the result type of the RunnableWithResult
if such
is the read argumentrunnable
- a runnable to execute in the context of the active
transaction, on any thread
runnable
is a RunnableWithResult
, then the privileged runnable will
inherit its result when it completes
IllegalStateException
- on an attempt by a thread that does not
own the active transaction to create a privileged runnable. This
prevents "theft" of transactions by malicious code. Note also
that this implies an exception if there is no active transaction at
the time of this callTransactionUtil.createPrivilegedRunnable(TransactionalEditingDomain, RunnableWithResult)
void dispose()
Note that editing domains registered on the extension point may not be disposed.
|
Copyright 2002, 2007 IBM Corporation and others. All Rights Reserved. |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |