/// <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);
                }
            }
        }