in MySql.Web/src/SessionProvider.cs [520:663]
private SessionStateStoreData GetSessionStoreItem(bool lockRecord,
HttpContext context,
string id,
out bool locked,
out TimeSpan lockAge,
out object lockId,
out SessionStateActions actionFlags)
{
// Initial values for return value and out parameters.
SessionStateStoreData item = null;
lockAge = TimeSpan.Zero;
lockId = null;
locked = false;
actionFlags = SessionStateActions.None;
// MySqlCommand for database commands.
MySqlCommand cmd = null;
// serialized SessionStateItemCollection.
byte[] serializedItems = null;
// True if a record is found in the database.
bool foundRecord = false;
// True if the returned session item is expired and needs to be deleted.
bool deleteData = false;
// Timeout value from the data store.
int timeout = 0;
try
{
using (MySqlConnection conn = new MySqlConnection(connectionString))
{
conn.Open();
// lockRecord is True when called from GetItemExclusive and
// False when called from GetItem.
// Obtain a lock if possible. Ignore the record if it is expired.
if (lockRecord)
{
cmd = new MySqlCommand(
"UPDATE my_aspnet_sessions SET " +
" Locked = 1, LockDate = NOW()" +
" WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId AND" +
" Locked = 0 AND Expires > NOW()", conn);
cmd.Parameters.AddWithValue("@SessionId", id);
cmd.Parameters.AddWithValue("@ApplicationId", ApplicationId);
if (cmd.ExecuteNonQuery() == 0)
{
// No record was updated because the record was locked or not found.
locked = true;
}
else
{
// The record was updated.
locked = false;
}
}
// Retrieve the current session item information.
cmd = new MySqlCommand(
"SELECT NOW(), Expires , SessionItems, LockId, Flags, Timeout, " +
" LockDate, Locked " +
" FROM my_aspnet_sessions" +
" WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId", conn);
cmd.Parameters.AddWithValue("@SessionId", id);
cmd.Parameters.AddWithValue("@ApplicationId", ApplicationId);
// Retrieve session item data from the data source.
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
DateTime now = reader.GetDateTime(0);
DateTime expires = reader.GetDateTime(1);
if (now.CompareTo(expires) > 0)
{
//The record was expired. Mark it as not locked.
locked = false;
// The session was expired. Mark the data for deletion.
deleteData = true;
}
else
{
foundRecord = true;
}
object items = reader.GetValue(2);
serializedItems = (items is DBNull) ? null : (byte[])items;
lockId = reader.GetValue(3);
if (lockId is DBNull)
lockId = (int)0;
actionFlags = (SessionStateActions)(reader.GetInt32(4));
timeout = reader.GetInt32(5);
DateTime lockDate = reader.GetDateTime(6);
lockAge = now.Subtract(lockDate);
// If it's a read-only session set locked to the current lock
// status (writable sessions have already done this)
if (!lockRecord)
locked = reader.GetBoolean(7);
}
}
// The record was not found. Ensure that locked is false.
if (!foundRecord)
locked = false;
// If the record was found and you obtained a lock, then set
// the lockId, clear the actionFlags,
// and create the SessionStateStoreItem to return.
if (foundRecord && !locked)
{
lockId = (int)(lockId) + 1;
cmd = new MySqlCommand("UPDATE my_aspnet_sessions SET" +
" LockId = @LockId, Flags = 0 " +
" WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId", conn);
cmd.Parameters.AddWithValue("@LockId", lockId);
cmd.Parameters.AddWithValue("@SessionId", id);
cmd.Parameters.AddWithValue("@ApplicationId", ApplicationId);
cmd.ExecuteNonQuery();
// If the actionFlags parameter is not InitializeItem,
// deserialize the stored SessionStateItemCollection.
if (actionFlags == SessionStateActions.InitializeItem)
{
item = CreateNewStoreData(context, (int)sessionStateConfig.Timeout.TotalMinutes);
}
else
{
item = Deserialize(context, serializedItems, timeout);
}
}
}
}
catch (MySqlException e)
{
HandleMySqlException(e, "GetSessionStoreItem");
}
return item;
}