T
- The type of the property. This type must be immutable (meaning it cannot be changed after it
is constructed) or it must be treated as such.public class TransactedProperty<T> extends TransactedObject
Transaction
, which guarantees
snapshot isolation for all properties in a TransactionContext
.Constructor and Description |
---|
TransactedProperty(TransactionContext context,
Object owner)
Initializes a new property with a specified context and owner.
|
TransactedProperty(TransactionContext context,
Object owner,
T value)
Initializes a new property with a specified context, owner, and value.
|
Modifier and Type | Method and Description |
---|---|
Transaction |
_notify(Object notifyDetails,
Transaction chainedTransaction)
Notifies interested parties of changes to this transacted object.
|
void |
abort(Transaction transaction,
Object modificationDetails)
Aborts the specified modification.
|
void |
addChanged(EventHandler<TransactedPropertyChangedEventArgs<T>> value)
|
void |
cleanup(Object modificationDetails)
Cleans up modifications that are no longer visible to any transaction.
|
Object |
commit(Transaction transaction,
Object modificationDetails)
Commits the specified modification.
|
void |
ensureValue(Transaction transaction)
At
Transaction.commit() time, ensures that the value of this property, as seen by a
given Transaction , has not changed. |
T |
getValue(Transaction transaction)
Gets the value of this transacted property in the context of the given transaction,
guaranteeing snapshot isolation.
|
void |
removeChanged(EventHandler<TransactedPropertyChangedEventArgs<T>> value)
|
void |
setValue(Transaction transaction,
T value)
Sets the value of this property in the context of the specified transaction.
|
String |
toString()
Get a
String that represents the value of this transacted property. |
boolean |
validateModification(Transaction transaction,
Object modificationDetails)
Verifies a modification to ensure that it is still valid after other transactions
have potentially committed modifications to this object.
|
checkTransaction, getContext, getOwner
public TransactedProperty(@Nonnull TransactionContext context, Object owner)
T
.context
- The context in which this property can be read and modified.owner
- The object that owns this property.public TransactedProperty(@Nonnull TransactionContext context, Object owner, T value)
context
- The context in which this property can be read and modified.owner
- The object that owns this property.value
- The initial value of the property.public final void addChanged(EventHandler<TransactedPropertyChangedEventArgs<T>> value)
Committed
(add
/ remove
).
See the Remarks section for more information.
This event is raised in the thread that committed the transaction and is raised inside the commit lock. This means that it is only raised by one thread at a time and it is raised once per transaction in the order in which the transactions are committed.
When this event is raised, all values modified by the transaction have
already been committed and will be visible to a transaction started within
an event handler. Attempting to commit another transaction within a handler
hooked up to this event will result in an IllegalStateException
,
however. If additional changes are necessary, use the
ChainedTransaction
(get
) and do not manually
commit it. It will be automatically committed after all handlers for this event
have finished executing. It is guaranteed that the chained transaction will commit
immediately after all event handlers return, before any other transaction can commit,
and that it will not raise a TransactionConflictException
.
It is very important that subscribers to this event execute very quickly in order to avoid blocking the entire transaction system.
value
- The handler.public final void removeChanged(EventHandler<TransactedPropertyChangedEventArgs<T>> value)
Committed
(add
/ remove
).
See the Remarks section for more information.
This event is raised in the thread that committed the transaction and is raised inside the commit lock. This means that it is only raised by one thread at a time and it is raised once per transaction in the order in which the transactions are committed.
When this event is raised, all values modified by the transaction have
already been committed and will be visible to a transaction started within
an event handler. Attempting to commit another transaction within a handler
hooked up to this event will result in an IllegalStateException
,
however. If additional changes are necessary, use the
ChainedTransaction
(get
) and do not manually
commit it. It will be automatically committed after all handlers for this event
have finished executing. It is guaranteed that the chained transaction will commit
immediately after all event handlers return, before any other transaction can commit,
and that it will not raise a TransactionConflictException
.
It is very important that subscribers to this event execute very quickly in order to avoid blocking the entire transaction system.
value
- The handler.public String toString()
String
that represents the value of this transacted property.
This method creates a new Transaction
in which to obtain the current
value of this transacted property.
public final T getValue(@Nonnull Transaction transaction)
This method guarantees snapshot isolation. This means that it will return either
the last value that was passed to TransactedProperty.setValue(agi.foundation.Transaction, T)
within the same
transaction
, or the value of this transacted property that was in place when
the transaction
started. This is true even if other transactions
have committed a change to this transacted property since this transaction started.
If you need to ensure that the value returned by this method is the latest one,
call TransactedProperty.ensureValue(agi.foundation.Transaction)
. When a transaction is committed, a
TransactionConflictException
will be raised if an ensured value
was changed by a previously committed transaction.
transaction
- The transaction in which to obtain the value of the property.public final void ensureValue(@Nonnull Transaction transaction)
Transaction.commit()
time, ensures that the value of this property, as seen by a
given Transaction
, has not changed. If another transaction commits a change to this
property after the specified transaction
starts, the specified transaction
will throw TransactionConflictException
when it is committed.transaction
- The transaction in which to ensure that the value of the property does not change.public final void setValue(@Nonnull Transaction transaction, T value)
Transaction.commit()
is called.
Calling this method may cause a TransactionConflictException
to be raised at
Transaction.commit()
time. See the Remarks section for more information.
Calling this method may cause the transaction
to raise a
TransactionConflictException
at commit time. This will happen if
another transaction changes this same TransactedProperty
and it commits
after this transaction starts. Consider using
TransactionContext.doTransactionally(agi.foundation.compatibility.Action1<agi.foundation.Transaction>)
to automatically retry a transaction
until it commits successfully.
transaction
- The transaction in which to set the value.value
- The new value of the property.public void cleanup(Object modificationDetails)
Typically, historical values are maintained as a linked list, where the previous (older)
modification is found by traversing the Next
property of a given value body. When
this method is called, the value body referenced by the Next
property is no longer
needed. It should be set to null
so that it can be reclaimed by the garbage
collector.
cleanup
in class TransactedObject
modificationDetails
- The last modification that is still visible to transactions. Any modifications
after this one can be cleaned up.public Object commit(Transaction transaction, Object modificationDetails)
This method is called only if TransactedProperty.validateModification(agi.foundation.Transaction, java.lang.Object)
returns
true
, and it is called without the possibility of an intervening transaction committing.
Therefore, it is not necessary to revalidate the modification.
commit
in class TransactedObject
transaction
- The committing transaction.modificationDetails
- The modification to commit. This is the object that was passed to
Transaction.addModification(agi.foundation.infrastructure.threading.TransactedObject, java.lang.Object)
.TransactedProperty._notify(java.lang.Object, agi.foundation.Transaction)
method after all transacted objects have been committed.
If this method returns null
, TransactedProperty._notify(java.lang.Object, agi.foundation.Transaction)
will not be called.public void abort(Transaction transaction, Object modificationDetails)
abort
in class TransactedObject
transaction
- The aborting transaction.modificationDetails
- The modification to abort. This is the object that was passed to
Transaction.addModification(agi.foundation.infrastructure.threading.TransactedObject, java.lang.Object)
.public boolean validateModification(Transaction transaction, Object modificationDetails)
If this method returns false
, the transaction will raise a
TransactionConflictException
.
validateModification
in class TransactedObject
transaction
- The validating transaction.modificationDetails
- The modification to validate. This is the object that was passed to
Transaction.addModification(agi.foundation.infrastructure.threading.TransactedObject, java.lang.Object)
.true
if the modification is still valid; otherwise false
.public Transaction _notify(Object notifyDetails, Transaction chainedTransaction)
_notify
in class TransactedObject
notifyDetails
- The instance returned by TransactedProperty.commit(agi.foundation.Transaction, java.lang.Object)
. Usually this contains details of the modification.chainedTransaction
- A transaction that can be used to make additional changes that will be committed immediately after
the current transaction finishes committing. This parameter may be null
, in which
case a new transaction should be created for this purpose and returned.chainedTransaction
if it is non-null, or the new chained transaction if
chainedTransaction
was null
and a chained transaction
was required.