public abstract class ForwardingDOMDataReadWriteTransaction extends com.google.common.collect.ForwardingObject implements DOMDataReadWriteTransaction
DOMDataReadWriteTransaction
implementation which forwards all interface
method invocation to a delegate instance.Constructor and Description |
---|
ForwardingDOMDataReadWriteTransaction() |
Modifier and Type | Method and Description |
---|---|
boolean |
cancel()
Cancels the transaction.
|
com.google.common.util.concurrent.ListenableFuture<org.opendaylight.yangtools.yang.common.RpcResult<TransactionStatus>> |
commit()
Deprecated.
|
protected abstract DOMDataReadWriteTransaction |
delegate() |
void |
delete(LogicalDatastoreType store,
org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
Removes a piece of data from specified path.
|
com.google.common.util.concurrent.CheckedFuture<Boolean,ReadFailedException> |
exists(LogicalDatastoreType store,
org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
Checks if data is available in the logical data store located at provided path.
|
Object |
getIdentifier() |
void |
merge(LogicalDatastoreType store,
org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path,
org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?> data)
Merges a piece of data with the existing data at a specified path.
|
void |
put(LogicalDatastoreType store,
org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path,
org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?> data)
Stores a piece of data at the specified path.
|
com.google.common.util.concurrent.CheckedFuture<com.google.common.base.Optional<org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>,ReadFailedException> |
read(LogicalDatastoreType store,
org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
Reads data from provided logical data store located at the provided path.
|
com.google.common.util.concurrent.CheckedFuture<Void,TransactionCommitFailedException> |
submit()
Submits this transaction to be asynchronously applied to update the logical data tree.
|
public ForwardingDOMDataReadWriteTransaction()
@Nonnull protected abstract DOMDataReadWriteTransaction delegate()
delegate
in class com.google.common.collect.ForwardingObject
public com.google.common.util.concurrent.CheckedFuture<com.google.common.base.Optional<org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>,ReadFailedException> read(LogicalDatastoreType store, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
DOMDataReadTransaction
If the target is a subtree, then the whole subtree is read (and will be accessible from the returned data object).
read
in interface DOMDataReadTransaction
store
- Logical data store from which read should occur.path
- Path which uniquely identifies subtree which client want to
readReadFailedException
or an exception derived from ReadFailedException.public com.google.common.util.concurrent.CheckedFuture<Boolean,ReadFailedException> exists(LogicalDatastoreType store, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
DOMDataReadTransaction
Note: a successful result from this method makes no guarantee that a subsequent call to DOMDataReadTransaction.read(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)
will succeed. It is possible that the data resides in a data store on a remote node and, if that
node goes down or a network failure occurs, a subsequent read would fail. Another scenario is if
the data is deleted in between the calls to exists
and read
exists
in interface DOMDataReadTransaction
store
- Logical data store from which read should occur.path
- Path which uniquely identifies subtree which client want to
check existence ofReadFailedException
or an exception derived from ReadFailedException.public Object getIdentifier()
getIdentifier
in interface AsyncTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>
getIdentifier
in interface org.opendaylight.yangtools.concepts.Identifiable<Object>
public void put(LogicalDatastoreType store, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?> data)
DOMDataWriteTransaction
For more information on usage and examples, please see the documentation in AsyncWriteTransaction
.
If you need to make sure that a parent object exists but you do not want modify
its pre-existing state by using put, consider using DOMDataWriteTransaction.merge(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?, ?>)
instead.
put
in interface DOMDataWriteTransaction
store
- the logical data store which should be modifiedpath
- the data object pathdata
- the data object to be written to the specified pathpublic void merge(LogicalDatastoreType store, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?> data)
DOMDataWriteTransaction
For more information on usage and examples, please see the documentation in AsyncWriteTransaction
.
If you require an explicit replace operation, use DOMDataWriteTransaction.put(org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?, ?>)
instead.
merge
in interface DOMDataWriteTransaction
store
- the logical data store which should be modifiedpath
- the data object pathdata
- the data object to be merged to the specified pathpublic boolean cancel()
AsyncWriteTransaction
TransactionStatus.NEW
or TransactionStatus.SUBMITED
Invoking cancel() on TransactionStatus.FAILED
or
TransactionStatus.CANCELED
will have no effect, and transaction
is considered cancelled.
Invoking cancel() on finished transaction (future returned by AsyncWriteTransaction.submit()
already completed with TransactionStatus.COMMITED
) will always
fail (return false).cancel
in interface AsyncWriteTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>
public void delete(LogicalDatastoreType store, org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path)
AsyncWriteTransaction
delete
in interface AsyncWriteTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>
delete
in interface DOMDataWriteTransaction
store
- Logical data store which should be modifiedpath
- Data object pathpublic com.google.common.util.concurrent.CheckedFuture<Void,TransactionCommitFailedException> submit()
AsyncWriteTransaction
Note: It is strongly recommended to process the CheckedFuture result in an asynchronous manner rather than using the blocking get() method. See example usage below.
This call logically seals the transaction, which prevents the client from
further changing data tree using this transaction. Any subsequent calls to
AsyncWriteTransaction.delete(LogicalDatastoreType, Path)
will fail with
IllegalStateException
.
The transaction is marked as TransactionStatus.SUBMITED
and
enqueued into the data store back-end for processing.
Whether or not the commit is successful is determined by versioning
of the data tree and validation of registered commit participants
(AsyncConfigurationCommitHandler
)
if the transaction changes the data tree.
The effects of a successful commit of data depends on data change listeners
(AsyncDataChangeListener
) and commit participants
(AsyncConfigurationCommitHandler
) that are registered with the data broker.
private void doWrite( final int tries ) { WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction(); MyDataObject data = ...; InstanceIdentifier<MyDataObject> path = ...; writeTx.put( LogicalDatastoreType.OPERATIONAL, path, data ); Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() { public void onSuccess( Void result ) { // succeeded } public void onFailure( Throwable t ) { if( t instanceof OptimisticLockFailedException ) { if( ( tries - 1 ) > 0 ) { // do retry doWrite( tries - 1 ); } else { // out of retries } } else { // failed due to another type of TransactionCommitFailedException. } } ); } ... doWrite( 2 );
Transaction may fail because of multiple reasons, such as
OptimisticLockFailedException
. It is the responsibility of the
caller to create a new transaction and submit the same modification again in
order to update data tree. Warning: In most cases, retrying after an
OptimisticLockFailedException will result in a high probability of success.
However, there are scenarios, albeit unusual, where any number of retries will
not succeed. Therefore it is strongly recommended to limit the number of retries (2 or 3)
to avoid an endless loop.
DataValidationFailedException
. User should not retry to
create new transaction with same data, since it probably will fail again.
Initial state | Tx 1 | Tx 2 | Result |
---|---|---|---|
Empty | put(A,1) | put(A,2) | Tx 2 will fail, state is A=1 |
Empty | put(A,1) | merge(A,2) | A=2 |
Empty | merge(A,1) | put(A,2) | Tx 2 will fail, state is A=1 |
Empty | merge(A,1) | merge(A,2) | A=2 |
A=0 | put(A,1) | put(A,2) | Tx 2 will fail, A=1 |
A=0 | put(A,1) | merge(A,2) | A=2 |
A=0 | merge(A,1) | put(A,2) | Tx 2 will fail, A=1 |
A=0 | merge(A,1) | merge(A,2) | A=2 |
A=0 | delete(A) | put(A,2) | Tx 2 will fail, A does not exists |
A=0 | delete(A) | merge(A,2) | A=2 |
Initial state | Tx 1 | Tx 2 | Result |
---|---|---|---|
Empty | put(TOP,[]) | put(TOP,[]) | Tx 2 will fail, state is TOP=[] |
Empty | put(TOP,[]) | merge(TOP,[]) | TOP=[] |
Empty | put(TOP,[FOO=1]) | put(TOP,[BAR=1]) | Tx 2 will fail, state is TOP=[FOO=1] |
Empty | put(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | TOP=[FOO=1,BAR=1] |
Empty | merge(TOP,[FOO=1]) | put(TOP,[BAR=1]) | Tx 2 will fail, state is TOP=[FOO=1] |
Empty | merge(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | TOP=[FOO=1,BAR=1] |
TOP=[] | put(TOP,[FOO=1]) | put(TOP,[BAR=1]) | Tx 2 will fail, state is TOP=[FOO=1] |
TOP=[] | put(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | merge(TOP,[FOO=1]) | put(TOP,[BAR=1]) | Tx 2 will fail, state is TOP=[FOO=1] |
TOP=[] | merge(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | delete(TOP) | put(TOP,[BAR=1]) | Tx 2 will fail, state is empty store |
TOP=[] | delete(TOP) | merge(TOP,[BAR=1]) | state is TOP=[BAR=1] |
TOP=[] | put(TOP/FOO,1) | put(TOP/BAR,1]) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | put(TOP/FOO,1) | merge(TOP/BAR,1) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | merge(TOP/FOO,1) | put(TOP/BAR,1) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | merge(TOP/FOO,1) | merge(TOP/BAR,1) | state is TOP=[FOO=1,BAR=1] |
TOP=[] | delete(TOP) | put(TOP/BAR,1) | Tx 2 will fail, state is empty store |
TOP=[] | delete(TOP) | merge(TOP/BAR,1] | Tx 2 will fail, state is empty store |
TOP=[FOO=1] | put(TOP/FOO,2) | put(TOP/BAR,1) | state is TOP=[FOO=2,BAR=1] |
TOP=[FOO=1] | put(TOP/FOO,2) | merge(TOP/BAR,1) | state is TOP=[FOO=2,BAR=1] |
TOP=[FOO=1] | merge(TOP/FOO,2) | put(TOP/BAR,1) | state is TOP=[FOO=2,BAR=1] |
TOP=[FOO=1] | merge(TOP/FOO,2) | merge(TOP/BAR,1) | state is TOP=[FOO=2,BAR=1] |
TOP=[FOO=1] | delete(TOP/FOO) | put(TOP/BAR,1) | state is TOP=[BAR=1] |
TOP=[FOO=1] | delete(TOP/FOO) | merge(TOP/BAR,1] | state is TOP=[BAR=1] |
txA = broker.newWriteTransaction(); // allocates new transaction, data tree is empty txB = broker.newWriteTransaction(); // allocates new transaction, data tree is empty txA.put(CONFIGURATION, PATH, A); // writes to PATH value A txB.put(CONFIGURATION, PATH, B) // writes to PATH value B ListenableFuture futureA = txA.submit(); // transaction A is sealed and submitted ListenebleFuture futureB = txB.submit(); // transaction B is sealed and submittedCommit of transaction A will be processed asynchronously and data tree will be updated to contain value
A
for PATH
.
Returned ListenableFuture
will successfully complete once
state is applied to data tree.
Commit of Transaction B will fail, because previous transaction also
modified path in a concurrent way. The state introduced by transaction B
will not be applied. Returned ListenableFuture
object will fail
with OptimisticLockFailedException
exception, which indicates to
client that concurrent transaction prevented the submitted transaction from being
applied.
submit
in interface AsyncWriteTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>
TransactionCommitFailedException
or an exception
derived from TransactionCommitFailedException.@Deprecated public com.google.common.util.concurrent.ListenableFuture<org.opendaylight.yangtools.yang.common.RpcResult<TransactionStatus>> commit()
commit
in interface AsyncWriteTransaction<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?,?>>
Copyright © 2019 OpenDaylight. All rights reserved.