15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

628 ❘ ChaPTer 23 system.trAnsActiOns<br />

If the ambient transaction is different from the enlisted transaction, an exception is thrown. The<br />

implementation does not support changing the same value from within two different transactions. If you<br />

have this requirement, you can create a lock <strong>and</strong> wait for the lock to be released from one transaction before<br />

changing it within another transaction:<br />

public Transactional(T value)<br />

{<br />

if (Transaction.Current == null)<br />

{<br />

this.liveValue = value;<br />

}<br />

else<br />

{<br />

this.liveValue = default(T);<br />

GetEnlistment().Value = value;<br />

}<br />

}<br />

public Transactional()<br />

: this(default(T)) {}<br />

private ResourceManager GetEnlistment()<br />

{<br />

Transaction tx = Transaction.Current;<br />

Trace.Assert(tx != null, "Must be invoked with ambient transaction");<br />

}<br />

if (enlistedTransaction == null)<br />

{<br />

enlistment = new ResourceManager(this, tx);<br />

tx.EnlistVolatile(enlistment, EnlistmentOptions.None);<br />

enlistedTransaction = tx;<br />

return enlistment;<br />

}<br />

else if (enlistedTransaction == Transaction.Current)<br />

{<br />

return enlistment;<br />

}<br />

else<br />

{<br />

throw new TransactionException(<br />

"This class only supports enlisting with one transaction");<br />

}<br />

The property Value returns the value of the contained class <strong>and</strong> sets it. However, with transactions, you<br />

cannot just set <strong>and</strong> return the liveValue variable. This would be the case only if the object were outside<br />

a transaction. To make the code more readable, the property Value uses the methods GetValue() <strong>and</strong><br />

SetValue() in the implementation:<br />

public T Value<br />

{<br />

get { return GetValue(); }<br />

set { SetValue(value); }<br />

}<br />

The method GetValue() checks if an ambient transaction exists. If one doesn’t exist, the liveValue<br />

is returned. If there is an ambient transaction, the GetEnlistment() method shown earlier returns the<br />

resource manager, <strong>and</strong> with the Value property, the temporary value for the contained object within<br />

the transaction is returned.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!