## org.eclipse.emf.transaction
Interface TransactionalEditingDomain

All Superinterfaces:
  EditingDomain

All Known Subinterfaces:
  InternalTransactionalEditingDomain

All Known Implementing Classes:
  TransactionalEditingDomainImpl

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

As of the EMF Transaction 1.3 release, resource-set listeners may optionally implement a private interface to be notified when they are added to or removed from an editing domain.

Also since the 1.3 release, the new optional `TransactionalEditingDomain.Lifecycle` interface provides notifications, from editing domains that support this protocol, of transaction and editing-domain lifecycle changes.

See Also:
  `TransactionalCommandStack`, `Transaction`, `ResourceSetListener`, `ResourceSetListener.Internal`, `TransactionalEditingDomain.Lifecycle`, `TransactionalEditingDomainListener`

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.Lifecycle` Adapter interface provided by `TransactionalEditingDomain`s that support notification of life-cycle events to `TransactionalEditingDomainListener`s.
`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

### getID

    String getID()

  Obtains my unique ID. This is the ID under which I am registered in the `TransactionalEditingDomain.Registry` (if I am registered).

  Returns:
    my unique identifier
  See Also:
    `TransactionalEditingDomain.Registry.getEditingDomain(String)`

### setID

    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.

  Parameters:
    `id` - my new unique identifier
  Throws:
    `IllegalArgumentException` - if I am a statically registered domain
  See Also:
    `getID()`, `TransactionalEditingDomain.Registry.add(String, TransactionalEditingDomain)`

### addResourceSetListener

    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.

  Parameters:
    `l` - a new resource set listener
  Throws:
    `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()`

### removeResourceSetListener

    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.

  Parameters:
    `l` - a resource set listener to remove

### runExclusive

    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).

  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.

  Parameters:
    `read` - a read-only operation to execute
  Returns:
    the result of the read operation if it is a `RunnableWithResult` and the transaction did not roll back; `null`, otherwise
  Throws:
    `InterruptedException` - if the current thread is interrupted while waiting for access to the resource set
  See Also:
    `TransactionUtil#runExclusive(RunnableWithResult)`, `Transaction.commit()`

### yield

    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.

### createPrivilegedRunnable

    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);
           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.

  Type Parameters:
    `T` - the result type of the `RunnableWithResult` if such is the `read` argument
  Parameters:
    `runnable` - a runnable to execute in the context of the active transaction, on any thread
  Returns:
    the privileged runnable. If the wrapped `runnable` is a `RunnableWithResult`, then the privileged runnable will inherit its result when it completes
  Throws:
    `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
  See Also:
    `TransactionUtil.createPrivilegedRunnable(TransactionalEditingDomain, RunnableWithResult)`

### dispose

    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.