#region License
/*
* Copyright 2002-2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
namespace Spring.Transaction.Support{
/// <summary>
/// Convenient base class for resource holders.
/// </summary>
/// <remarks>
/// <p>
/// Features rollback-only support transactions. Can expire after a certain number of
/// seconds or milliseconds, to determine transactional timeouts.
/// </p>
/// </remarks>
/// <author>Juergen Hoeller</author>
/// <author>Griffin Caprio (.NET)</author>
public abstract class ResourceHolderSupport
{
private bool synchronizedWithTransaction = false;
private bool rollbackOnly = false;
private DateTime deadline;
private int referenceCount = 0;
/// <summary>
/// Mark the resource as synchronized with a transaction.
/// </summary>
public bool SynchronizedWithTransaction
{
get { return synchronizedWithTransaction; }
set { synchronizedWithTransaction = value; }
}
/// <summary>
/// Get or set whether the resource is synchronized with a transaction.
/// </summary>
/// <value><c>true</c> if synchronized; otherwise, <c>false</c>.</value>
public bool RollbackOnly
{
get { return rollbackOnly; }
set { rollbackOnly = value;}
}
/// <summary>
/// Return the expiration deadline of this object.
/// </summary>
public DateTime Deadline
{
get { return deadline; }
}
/// <summary>
/// Return whether this object has an associated timeout.
/// </summary>
public bool HasTimeout
{
get { return ( deadline != DateTime.MinValue ); }
}
/// <summary>
/// Return the time to live for this object in seconds.
/// </summary>
/// <remarks>
/// <p>
/// Rounds up eagerly, e.g. '9.00001' to '10'.
/// </p>
/// </remarks>
/// <exception cref="System.ArgumentException">
/// If no deadline has been set.
/// </exception>
public int TimeToLiveInSeconds
{
get
{
int secs = (int)Math.Ceiling( TimeToLiveInMilliseconds / 1000 );
checkTransactionTimeout(secs <= 0);
return secs;
}
}
/// <summary>
/// Return the time to live for this object in milliseconds.
/// </summary>
/// <exception cref="System.ArgumentException">
/// If no deadline has been set.
/// </exception>
public double TimeToLiveInMilliseconds
{
get
{
if ( deadline == DateTime.MinValue )
{
throw new ArgumentException( "No deadline specified for this resource holder.");
}
TimeSpan duration = deadline - DateTime.Now;
checkTransactionTimeout(duration.TotalMilliseconds <= 0);
if (duration.TotalMilliseconds > 0)
{
return duration.TotalMilliseconds;
}
else
{
return 0;
}
}
}
/// <summary>
/// Sets the timeout for this object in milliseconds.
/// </summary>
/// <value>Number of milliseconds until expiration.</value>
public long TimeoutInMillis
{
set
{
deadline = DateTime.Now.AddMilliseconds(value);
}
}
/// <summary>
/// Sets the timeout for this object in seconds.
/// </summary>
/// <value>Number of seconds until expiration.</value>
public int TimeoutInSeconds
{
set
{
TimeoutInMillis = value * 1000;
}
}
private void checkTransactionTimeout(bool deadlineReached)
{
if (deadlineReached)
{
RollbackOnly = true;
throw new TransactionTimedOutException("Transaction timed out: deadline was " + Deadline);
}
}
/// <summary>
/// Clear the transaction state of this resource holder.
/// </summary>
public virtual void Clear()
{
synchronizedWithTransaction = false;
rollbackOnly = false;
deadline = DateTime.MinValue;
}
/// <summary>
/// Increase the reference count by one because the holder has been requested.
/// </summary>
public void Requested()
{
referenceCount++;
}
/// <summary>
/// Decrease the reference count by one because the holder has been released.
/// </summary>
public void Released()
{
referenceCount--;
}
/// <summary>
/// Return wheterh there are still open references to this holder
/// </summary>
public bool IsOpen
{
get
{
return (referenceCount > 0);
}
}
}
}
|