/// <summary> /// Acquires an application level lock on the connection which is session scoped. /// </summary> /// <param name="lockId">Identity of the lock.</param> private void GetAppLock(Guid lockId) { using (SqlCommand cmdGetAppLock = _conn.CreateCommand()) { cmdGetAppLock.CommandText = @"sp_getapplock"; cmdGetAppLock.CommandType = CommandType.StoredProcedure; SqlUtils.AddCommandParameter( cmdGetAppLock, "@Resource", SqlDbType.NVarChar, ParameterDirection.Input, 255 * 2, lockId.ToString()); SqlUtils.AddCommandParameter( cmdGetAppLock, "@LockMode", SqlDbType.NVarChar, ParameterDirection.Input, 32 * 2, "Exclusive"); SqlUtils.AddCommandParameter( cmdGetAppLock, "@LockOwner", SqlDbType.NVarChar, ParameterDirection.Input, 32 * 2, "Session"); SqlUtils.AddCommandParameter( cmdGetAppLock, "@LockTimeout", SqlDbType.Int, ParameterDirection.Input, 0, GlobalConstants.DefaultLockTimeOut); SqlParameter returnValue = SqlUtils.AddCommandParameter( cmdGetAppLock, "@RETURN_VALUE", SqlDbType.Int, ParameterDirection.ReturnValue, 0, 0); cmdGetAppLock.ExecuteNonQuery(); // If time-out or other errors happen. if ((int)returnValue.Value < 0) { throw new ShardManagementException( ShardManagementErrorCategory.General, ShardManagementErrorCode.LockNotAcquired, Errors._Store_SqlOperation_LockNotAcquired, lockId); } } }
public virtual IStoreResults ExecuteOperation(string operationName, XElement operationData) { return(SqlUtils.WithSqlExceptionHandling <IStoreResults>(() => { SqlResults results = new SqlResults(); using (SqlCommand cmd = _conn.CreateCommand()) using (XmlReader input = operationData.CreateReader()) { cmd.Transaction = _tran; cmd.CommandText = operationName; cmd.CommandType = CommandType.StoredProcedure; SqlUtils.AddCommandParameter(cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, -1, new SqlXml(input)); SqlParameter result = SqlUtils.AddCommandParameter(cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0); using (SqlDataReader reader = cmd.ExecuteReader()) { results.Fetch(reader); } // Output parameter will be used to specify the outcome. results.Result = (StoreResult)result.Value; } return results; })); }
private void ReleaseAppLock(Guid lockId) { using (SqlCommand cmdReleaseAppLock = _conn.CreateCommand()) { cmdReleaseAppLock.CommandText = @"sp_releaseapplock"; cmdReleaseAppLock.CommandType = CommandType.StoredProcedure; SqlUtils.AddCommandParameter( cmdReleaseAppLock, "@Resource", SqlDbType.NVarChar, ParameterDirection.Input, 255 * 2, lockId.ToString()); SqlUtils.AddCommandParameter( cmdReleaseAppLock, "@LockOwner", SqlDbType.NVarChar, ParameterDirection.Input, 32 * 2, "Session"); SqlParameter returnValue = SqlUtils.AddCommandParameter( cmdReleaseAppLock, "@RETURN_VALUE", SqlDbType.Int, ParameterDirection.ReturnValue, 0, 0); try { cmdReleaseAppLock.ExecuteNonQuery(); } catch (Exception) { // ignore all exceptions. return; } // If parameter validation or other errors happen. if ((int)returnValue.Value < 0) { throw new ShardManagementException( ShardManagementErrorCategory.General, ShardManagementErrorCode.LockNotReleased, Errors._Store_SqlOperation_LockNotReleased, lockId); } } }
/// <summary> /// Performs validation that the local representation is as up-to-date /// as the representation on the backing data store. /// </summary> /// <param name="conn">Connection used for validation.</param> /// <param name="manager">ShardMapManager reference.</param> /// <param name="shardMap">Shard map for the mapping.</param> /// <param name="storeMapping">Mapping to validate.</param> internal static void ValidateMapping( SqlConnection conn, ShardMapManager manager, IStoreShardMap shardMap, IStoreMapping storeMapping) { Stopwatch stopwatch = Stopwatch.StartNew(); SqlResults lsmResult = new SqlResults(); XElement xeValidate = StoreOperationRequestBuilder.ValidateShardMappingLocal(shardMap.Id, storeMapping.Id); using (SqlCommand cmd = conn.CreateCommand()) using (XmlReader input = xeValidate.CreateReader()) { cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardMappingLocal; cmd.CommandType = CommandType.StoredProcedure; SqlUtils.AddCommandParameter( cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, new SqlXml(input)); SqlParameter resultParam = SqlUtils.AddCommandParameter( cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0); using (SqlDataReader reader = cmd.ExecuteReader()) { lsmResult.Fetch(reader); } // Output parameter will be used to specify the outcome. lsmResult.Result = (StoreResult)resultParam.Value; } stopwatch.Stop(); Tracer.TraceInfo( TraceSourceConstants.ComponentNames.Shard, "ValidateMapping", "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}", storeMapping.StoreShard.Location, conn.ConnectionString, lsmResult.Result, stopwatch.Elapsed); if (lsmResult.Result != StoreResult.Success) { if (lsmResult.Result == StoreResult.ShardMapDoesNotExist) { manager.Cache.DeleteShardMap(shardMap); } else if (lsmResult.Result == StoreResult.MappingDoesNotExist) { // Only evict from cache is mapping is no longer present, // for Offline mappings, we don't even retry, so same request // will continue to go to the LSM. manager.Cache.DeleteMapping(storeMapping); } // Possible errors are: // StoreResult.ShardMapDoesNotExist // StoreResult.MappingDoesNotExist // StoreResult.MappingIsOffline // StoreResult.ShardVersionMismatch // StoreResult.StoreVersionMismatch // StoreResult.MissingParametersForStoredProcedure throw StoreOperationErrorHandler.OnValidationErrorLocal( lsmResult, shardMap, storeMapping.StoreShard.Location, "ValidateMapping", StoreOperationRequestBuilder.SpValidateShardLocal); } Debug.Assert(lsmResult.Result == StoreResult.Success); }
/// <summary> /// Asynchronously performs validation that the local representation is as /// up-to-date as the representation on the backing data store. /// </summary> /// <param name="conn">Connection used for validation.</param> /// <param name="manager">ShardMapManager reference.</param> /// <param name="shardMap">Shard map for the shard.</param> /// <param name="shard">Shard to validate.</param> /// <returns>A task to await validation completion</returns> internal static async Task ValidateShardAsync( SqlConnection conn, ShardMapManager manager, IStoreShardMap shardMap, IStoreShard shard ) { Stopwatch stopwatch = Stopwatch.StartNew(); SqlResults lsmResult = new SqlResults(); XElement xeValidate = StoreOperationRequestBuilder.ValidateShardLocal(shardMap.Id, shard.Id, shard.Version); using (SqlCommand cmd = conn.CreateCommand()) using (XmlReader input = xeValidate.CreateReader()) { cmd.CommandText = StoreOperationRequestBuilder.SpValidateShardLocal; cmd.CommandType = CommandType.StoredProcedure; SqlUtils.AddCommandParameter( cmd, "@input", SqlDbType.Xml, ParameterDirection.Input, 0, new SqlXml(input)); SqlParameter resultParam = SqlUtils.AddCommandParameter( cmd, "@result", SqlDbType.Int, ParameterDirection.Output, 0, 0); using (SqlDataReader reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false)) { await lsmResult.FetchAsync(reader).ConfigureAwait(false); } // Output parameter will be used to specify the outcome. lsmResult.Result = (StoreResult)resultParam.Value; } stopwatch.Stop(); Tracer.TraceInfo( TraceSourceConstants.ComponentNames.Shard, "ValidateShardAsync", "Complete; Shard: {0}; Connection: {1}; Result: {2}; Duration: {3}", shard.Location, conn.ConnectionString, lsmResult.Result, stopwatch.Elapsed); if (lsmResult.Result != StoreResult.Success) { if (lsmResult.Result == StoreResult.ShardMapDoesNotExist) { manager.Cache.DeleteShardMap(shardMap); } // Possible errors are: // StoreResult.ShardMapDoesNotExist // StoreResult.ShardDoesNotExist // StoreResult.ShardVersionMismatch // StoreResult.StoreVersionMismatch // StoreResult.MissingParametersForStoredProcedure throw StoreOperationErrorHandler.OnValidationErrorLocal( lsmResult, shardMap, shard.Location, "ValidateShardAsync", StoreOperationRequestBuilder.SpValidateShardLocal); } }