/// <summary> /// Determine if the requested lock can be acquired /// </summary> /// <remarks>This does not hold any locks outside of the call, making it less expensive for probing locks.</remarks> /// <returns>0 if the lock can't be granted, 1 if it can be.</returns> public int PeekApplicationLock(string name, SqlLockMode lockMode) { int result; using (var command = CreateCommand("SELECT APPLOCK_TEST('public', @Resource, @LockMode, @LockOwner)", GetConnection(), CommandType.Text, true)) { CreateParameter(command, "Resource", DbType.String, ParameterDirection.Input, 255, name); CreateParameter(command, "LockMode", DbType.String, ParameterDirection.Input, 32, lockMode.ToString()); CreateParameter(command, "LockOwner", DbType.String, ParameterDirection.Input, 32, "Session"); result = ExecuteScalar <int>(command, false); } return(result); }
/// <summary> /// Attempt to get the specified lock in the database, which will remain associated with this object /// </summary> /// <param name="name"></param> /// <param name="lockMode"></param> /// <param name="lockTimeoutMilliseconds"></param> /// <returns>0 if the lock was granted, 1 if it was granted only after waiting, negative numbers for various failures.</returns> public int GetApplicationLock(string name, SqlLockMode lockMode, int lockTimeoutMilliseconds) { //if necessary bump out our query timeout if (lockTimeoutMilliseconds > 0) { var lockSeconds = lockTimeoutMilliseconds / 1000; _queryTimeout = Math.Max(lockSeconds, _queryTimeout); } using (var command = CreateCommand("sys.sp_GetAppLock", GetConnection(), CommandType.StoredProcedure, true)) { var transaction = _transaction; if (transaction == null) { if (command.Connection.State != ConnectionState.Open) { command.Connection.Open(); } transaction = command.Connection.BeginTransaction(); } command.Transaction = transaction; CreateParameter(command, "Resource", DbType.String, ParameterDirection.Input, 255, name); CreateParameter(command, "LockMode", DbType.String, ParameterDirection.Input, 32, lockMode.ToString()); CreateParameter(command, "LockOwner", DbType.String, ParameterDirection.Input, 32, "Transaction"); CreateParameter(command, "LockTimeout", DbType.String, ParameterDirection.Input, 32, lockTimeoutMilliseconds.ToString()); var returnValue = CreateParameter(command, "ReturnValue", DbType.Int32, ParameterDirection.ReturnValue); command.CommandTimeout = _queryTimeout; ExecuteNonQuery(command, false); if ((returnValue.Value == null) || (returnValue.Value == DBNull.Value)) { transaction.SafeDispose(); return(-100); } else { _transaction = transaction; //since this is the true scope of our lock. return((int)returnValue.Value); } } }