Interface TransactionalEditingDomain

All Superinterfaces:
All Known Subinterfaces:
All Known Implementing Classes:

public interface TransactionalEditingDomain
extends EditingDomain

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">

     // in code, access the registered editing domain by:

     TransactionalEditingDomain myDomain = TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain(

See the package documentation for further details of editing domain usage.

See Also:
TransactionalCommandStack, Transaction, ResourceSetListener

Nested Class Summary
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()
Obtains my unique ID. This is the ID under which I am registered in the TransactionalEditingDomain.Registry (if I am registered).

my unique identifier
See Also:


void setID(String id)
Sets my unique ID. If I am currently registered in the 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 domain
See Also:
getID(), TransactionalEditingDomain.Registry.add(String, TransactionalEditingDomain)


void addResourceSetListener(ResourceSetListener l)
Adds a resource set listener to me, to receive notifications of changes to the resource set when transactions commit. This method has no effect if the specified listeners is already attached to me.

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)
See Also:
ResourceSetListener.isPrecommitOnly(), ResourceSetListener.isPostcommitOnly()


void removeResourceSetListener(ResourceSetListener l)
Removes a resource set listener from me. This method has no effect if the listener is not currently attached to me.

l - a resource set listener to remove


Object runExclusive(Runnable read)
                    throws InterruptedException
Runs an operation that requires exclusive access to my resource set, for reading. The specified runnable is executed in a read-only transaction. If the runnable implements the 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).

read - a read-only operation to execute
the result of the read operation if it is a RunnableWithResult and the transaction did not roll back; null, otherwise
InterruptedException - if the current thread is interrupted while waiting for access to the resource set
See Also:


void yield()
Temporarily yields access to another read-only transaction. The 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)
Wraps the specified 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);

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.

runnable - a runnable to execute in the context of the active transaction, on any thread
the privileged runnable. If the wrapped 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 call


void dispose()
Disposes of this editing domain and any resources that it has allocated. Editing domains must be disposed when they are no longer in use, but only by the client that created them (in case of sharing of editing domains).

Note that editing domains registered on the extension point may not be disposed.

Copyright 2002, 2007 IBM Corporation and others.
All Rights Reserved.