📄 sqlstateclientmanager.cs
字号:
cmd.ExecuteNonQuery();
}
catch (Exception e) {
HandleInsertException(conn.Connection, e, true, id);
}
}
finally {
DisposeOrReuseConnection(ref conn, usePooling);
}
}
void HandleInsertException(SqlConnection conn, Exception e, bool newItem, string id) {
SqlException sqlExpt = e as SqlException;
if (sqlExpt != null &&
sqlExpt.Number == SQL_ERROR_PRIMARY_KEY_VIOLATION &&
newItem) {
//Debug.Trace("SessionStateClientSet",
// "Insert failed because of primary key violation; just leave gracefully; id=" + id);
// It's possible that two threads (from the same session) are creating the session
// state, both failed to get it first, and now both tried to insert it.
// One thread may lose with a Primary Key Violation error. If so, that thread will
// just lose and exit gracefully.
}
else {
ThrowSqlConnectionException(conn, e);
}
}
internal class PartitionInfo : IDisposable {
ResourcePool _rpool;
internal PartitionInfo(ResourcePool rpool) {
_rpool = rpool;
}
internal object RetrieveResource() {
return _rpool.RetrieveResource();
}
internal void StoreResource(IDisposable o) {
_rpool.StoreResource(o);
}
protected virtual string TracingPartitionString {
get {
return String.Empty;
}
}
string GetTracingPartitionString() {
return TracingPartitionString;
}
public void Dispose() {
if (_rpool == null) {
return;
}
lock (this) {
if (_rpool != null) {
_rpool.Dispose();
_rpool = null;
}
}
}
};
internal class SqlPartitionInfo : PartitionInfo {
bool _useIntegratedSecurity;
string _sqlConnectionString;
string _tracingPartitionString;
SupportFlags _support = SupportFlags.Uninitialized;
string _appSuffix;
object _lock = new object();
bool _sqlInfoInited;
const string APP_SUFFIX_FORMAT = "x8";
const int APPID_MAX = 280;
const int SQL_2000_MAJ_VER = 8;
internal SqlPartitionInfo(ResourcePool rpool, bool useIntegratedSecurity, string sqlConnectionString)
: base(rpool) {
_useIntegratedSecurity = useIntegratedSecurity;
_sqlConnectionString = sqlConnectionString;
//Debug.Trace("PartitionInfo", "Created a new info, sqlConnectionString=" + sqlConnectionString);
}
internal bool UseIntegratedSecurity {
get { return _useIntegratedSecurity; }
}
internal string SqlConnectionString {
get { return _sqlConnectionString; }
}
internal SupportFlags SupportFlags {
get { return _support; }
set { _support = value; }
}
protected override string TracingPartitionString {
get {
if (_tracingPartitionString == null) {
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(_sqlConnectionString);
builder.Password = String.Empty;
builder.UserID = String.Empty;
_tracingPartitionString = builder.ConnectionString;
}
return _tracingPartitionString;
}
}
internal string AppSuffix {
get { return _appSuffix; }
}
void GetServerSupportOptions(SqlConnection sqlConnection) {
//Debug.Assert(SupportFlags == SupportFlags.Uninitialized);
SqlCommand cmd;
SqlDataReader reader = null;
SupportFlags flags = SupportFlags.None;
bool v2 = false;
SqlParameter p;
// First, check if the SQL server is running Whidbey scripts
cmd = new SqlCommand("Select name from sysobjects where type = 'P' and name = 'TempGetVersion'", sqlConnection);
cmd.CommandType = CommandType.Text;
try {
reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
if (reader.Read()) {
// This function first appears in Whidbey (v2). So we know it's
// at least 2.0 even without reading its content.
v2 = true;
}
}
catch (Exception e) {
SqlSessionStateStore.ThrowSqlConnectionException(sqlConnection, e);
}
finally {
if (reader != null) {
reader.Close();
reader = null;
}
}
if (!v2) {
if (s_usePartition) {
throw new HttpException(
SR.GetString(SR.Need_v2_SQL_Server_partition_resolver,
s_configPartitionResolverType, sqlConnection.DataSource, sqlConnection.Database));
}
else {
throw new HttpException(
SR.GetString(SR.Need_v2_SQL_Server));
}
}
// Then, see if it's SQL 2000 or above
cmd = new SqlCommand("dbo.GetMajorVersion", sqlConnection);
cmd.CommandType = CommandType.StoredProcedure;
p = cmd.Parameters.Add(new SqlParameter("@@ver", SqlDbType.Int));
p.Direction = ParameterDirection.Output;
try {
cmd.ExecuteNonQuery();
if ((int)p.Value >= SQL_2000_MAJ_VER) {
// For details, see the extensive doc in DoGet method.
flags |= SupportFlags.GetLockAge;
}
//Debug.Trace("PartitionInfo", "SupportFlags initialized to " + flags);
SupportFlags = flags;
}
catch (Exception e) {
SqlSessionStateStore.ThrowSqlConnectionException(sqlConnection, e);
}
}
internal void InitSqlInfo(SqlConnection sqlConnection) {
if (_sqlInfoInited) {
return;
}
lock (_lock) {
if (_sqlInfoInited) {
return;
}
GetServerSupportOptions(sqlConnection);
// Get AppSuffix info
SqlParameter p;
SqlCommand cmdTempGetAppId = new SqlCommand("dbo.TempGetAppID", sqlConnection);
cmdTempGetAppId.CommandType = CommandType.StoredProcedure;
cmdTempGetAppId.CommandTimeout = s_commandTimeout;
// AppDomainAppIdInternal will contain the whole metabase path of the request's app
// e.g. /lm/w3svc/1/root/fxtest
p = cmdTempGetAppId.Parameters.Add(new SqlParameter("@appName", SqlDbType.VarChar, APPID_MAX));
p.Value = HttpRuntime.AppDomainAppId;
p = cmdTempGetAppId.Parameters.Add(new SqlParameter("@appId", SqlDbType.Int));
p.Direction = ParameterDirection.Output;
p.Value = Convert.DBNull;
cmdTempGetAppId.ExecuteNonQuery();
//Debug.Assert(!Convert.IsDBNull(p), "!Convert.IsDBNull(p)");
int appId = (int) p.Value;
_appSuffix = (appId).ToString(APP_SUFFIX_FORMAT, CultureInfo.InvariantCulture);
_sqlInfoInited = true;
}
}
};
/*
Here are all the sprocs created for session state and how they're used:
CreateTempTables
- Called during setup
DeleteExpiredSessions
- Called by SQL agent to remove expired sessions
GetHashCode
- Called by sproc TempGetAppID
GetMajorVersion
- Called during setup
TempGetAppID
- Called when an asp.net application starts up
TempGetStateItem
- Used for ReadOnly session state
- Called by v1 asp.net
- Called by v1.1 asp.net against SQL 7
TempGetStateItem2
- Used for ReadOnly session state
- Called by v1.1 asp.net against SQL 2000
TempGetStateItem3
- Used for ReadOnly session state
- Called by v2 asp.net
TempGetStateItemExclusive
- Called by v1 asp.net
- Called by v1.1 asp.net against SQL 7
TempGetStateItemExclusive2
- Called by v1.1 asp.net against SQL 2000
TempGetStateItemExclusive3
- Called by v2 asp.net
TempGetVersion
- Called by v2 asp.net when an application starts up
TempInsertStateItemLong
- Used when creating a new session state with size > 7000 bytes
TempInsertStateItemShort
- Used when creating a new session state with size <= 7000 bytes
TempInsertUninitializedItem
- Used when creating a new uninitilized session state (cookieless="true" and regenerateExpiredSessionId="true" in config)
TempReleaseStateItemExclusive
- Used when a request that has acquired the session state (exclusively) hit an error during the page execution
TempRemoveStateItem
- Used when a session is abandoned
TempResetTimeout
- Used when a request (with an active session state) is handled by an HttpHandler which doesn't support IRequiresSessionState interface.
TempUpdateStateItemLong
- Used when updating a session state with size > 7000 bytes
TempUpdateStateItemLongNullShort
- Used when updating a session state where original size <= 7000 bytes but new size > 7000 bytes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -