/**
         * Execute the SQL select for update that will lock the proper database row.
         */
        protected override void ExecuteSQL(ConnectionAndTransactionHolder conn, string lockName, string expandedSQL)
        {
            try {
                using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, expandedSQL))
                {
                    AdoUtil.AddCommandParameter(cmd, 1, "lockName", lockName);

                    using (IDataReader rs = cmd.ExecuteReader())
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Lock '" + lockName + "' is being obtained: " + Thread.CurrentThread.Name);
                        }

                        if (!rs.Read())
                        {
                            throw new Exception(AdoJobStoreUtil.ReplaceTablePrefix("No row exists in table " + TablePrefixSubst + TableLocks + " for lock named: " + lockName, TablePrefix));
                        }
                    }
                }
            } catch (Exception sqle) {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(
                        "Lock '" + lockName + "' was not obtained by: " +
                        Thread.CurrentThread.Name);
                }

                throw new LockException("Failure obtaining db row lock: "
                                        + sqle.Message, sqle);
            }
        }
示例#2
0
        /// <summary>
        /// Execute the SQL that will lock the proper database row.
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="lockName"></param>
        /// <param name="expandedSQL"></param>
        /// <param name="expandedInsertSQL"></param>
        protected override void ExecuteSQL(ConnectionAndTransactionHolder conn, string lockName, string expandedSQL, string expandedInsertSQL)
        {
            try
            {
                using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, expandedSQL))
                {
                    AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                    int numUpdate = cmd.ExecuteNonQuery();

                    if (numUpdate < 1)
                    {
                        using (IDbCommand cmd2 = AdoUtil.PrepareCommand(conn, expandedInsertSQL))
                        {
                            AdoUtil.AddCommandParameter(cmd2, "lockName", lockName);

                            int res = cmd2.ExecuteNonQuery();

                            if (res != 1)
                            {
                                throw new Exception(AdoJobStoreUtil.ReplaceTablePrefix(
                                                        "No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks +
                                                        " for lock named: " + lockName, TablePrefix, SchedulerNameLiteral));
                            }
                        }
                    }
                }
            }
            catch (Exception sqle)
            {
                throw new LockException(
                          "Failure obtaining db row lock: " + sqle.Message, sqle);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="sql">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string sql, string defaultSQL, IDbProvider dbProvider) {
     log = LogManager.GetLogger(GetType());
     this.sql = defaultSQL;
     this.tablePrefix = tablePrefix;
     SQL = sql;
     adoUtil = new AdoUtil(dbProvider);
 }
        private async Task LockViaInsert(
            Guid requestorId,
            ConnectionAndTransactionHolder conn,
            string lockName,
            string sql,
            CancellationToken cancellationToken)
        {
            if (sql == null)
            {
                throw new ArgumentNullException(nameof(sql));
            }

            if (Log.IsDebugEnabled())
            {
                Log.DebugFormat("Inserting new lock row for lock: '{0}' being obtained: {1}", lockName, requestorId);
            }

            using var cmd = AdoUtil.PrepareCommand(conn, sql);
            AdoUtil.AddCommandParameter(cmd, "schedulerName", SchedName);
            AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

            if (await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false) != 1)
            {
                throw new InvalidOperationException(
                          AdoJobStoreUtil.ReplaceTablePrefix("No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks + " for lock named: " + lockName, TablePrefix));
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="sql">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string sql, string defaultSQL, IDbProvider dbProvider)
 {
     log              = LogManager.GetLogger(GetType());
     this.sql         = defaultSQL;
     this.tablePrefix = tablePrefix;
     SQL              = sql;
     adoUtil          = new AdoUtil(dbProvider);
 }
示例#6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="schedName">the scheduler name</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string schedName, string defaultSQL, string defaultInsertSQL, IDbProvider dbProvider)
 {
     this.schedName = schedName;
     this.tablePrefix = tablePrefix;
     SQL = defaultSQL;
     InsertSQL = defaultInsertSQL;
     adoUtil = new AdoUtil(dbProvider);
 }
示例#7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="schedName">the scheduler name</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string schedName, string defaultSQL, string defaultInsertSQL, IDbProvider dbProvider)
 {
     this.schedName   = schedName;
     this.tablePrefix = tablePrefix;
     SQL       = defaultSQL;
     InsertSQL = defaultInsertSQL;
     adoUtil   = new AdoUtil(dbProvider);
 }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="schedName">the scheduler name</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string schedName, string defaultSQL, string defaultInsertSQL, IDbProvider dbProvider)
 {
     log              = LogManager.GetLogger(GetType());
     this.schedName   = schedName;
     this.tablePrefix = tablePrefix;
     SQL              = defaultSQL;
     InsertSQL        = defaultInsertSQL;
     adoUtil          = new AdoUtil(dbProvider);
 }
示例#9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 public DBSemaphore(string tablePrefix, string schedName, string defaultSQL, string defaultInsertSQL, IDbProvider dbProvider)
 {
     log = LogManager.GetLogger(GetType());
     this.schedName = schedName;
     this.tablePrefix = tablePrefix;
     SQL = defaultSQL;
     InsertSQL = defaultInsertSQL;
     adoUtil = new AdoUtil(dbProvider);
 }
示例#10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="schedName">the scheduler name</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 protected DBSemaphore(string tablePrefix, string schedName, string defaultSQL, string defaultInsertSQL, IDbProvider dbProvider)
 {
     log              = NLog.LogManager.GetCurrentClassLogger();
     this.schedName   = schedName;
     this.tablePrefix = tablePrefix;
     SQL              = defaultSQL;
     InsertSQL        = defaultInsertSQL;
     adoUtil          = new AdoUtil(dbProvider);
 }
        private bool LockViaUpdate(ConnectionAndTransactionHolder conn, string lockName, string sql)
        {
            using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, sql))
            {
                AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                Log.DebugFormat("Lock '{0}' is being obtained: {1}", lockName, Thread.CurrentThread.Name);
                return(cmd.ExecuteNonQuery() >= 1);
            }
        }
示例#12
0
        private async Task <bool> LockViaUpdate(Guid requestorId, ConnectionAndTransactionHolder conn, string lockName, string sql)
        {
            using (DbCommand cmd = AdoUtil.PrepareCommand(conn, sql))
            {
                AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                Log.DebugFormat("Lock '{0}' is being obtained: {1}", lockName, requestorId);
                return(await cmd.ExecuteNonQueryAsync().ConfigureAwait(false) >= 1);
            }
        }
示例#13
0
        /// <summary>
        /// Execute the SQL select for update that will lock the proper database row.
        /// </summary>
        protected override void ExecuteSQL(ConnectionAndTransactionHolder conn, string lockName, string expandedSQL, string expandedInsertSQL)
        {
            try
            {
                using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, expandedSQL))
                {
                    AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                    bool found = false;
                    using (IDataReader rs = cmd.ExecuteReader())
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug("Lock '" + lockName + "' is being obtained: " + Thread.CurrentThread.Name);
                        }

                        found = rs.Read();
                    }

                    if (!found)
                    {
                        Log.Debug(
                            "Inserting new lock row for lock: '" + lockName + "' being obtained by thread: " +
                            Thread.CurrentThread.Name);

                        using (IDbCommand cmd2 = AdoUtil.PrepareCommand(conn, expandedInsertSQL))
                        {
                            AdoUtil.AddCommandParameter(cmd2, "lockName", lockName);
                            int res = cmd2.ExecuteNonQuery();

                            if (res != 1)
                            {
                                throw new Exception(AdoJobStoreUtil.ReplaceTablePrefix(
                                                        "No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks +
                                                        " for lock named: " + lockName, TablePrefix, SchedulerNameLiteral));
                            }
                        }
                    }
                }
            }
            catch (Exception sqle)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug(
                        "Lock '" + lockName + "' was not obtained by: " +
                        Thread.CurrentThread.Name);
                }

                throw new LockException("Failure obtaining db row lock: "
                                        + sqle.Message, sqle);
            }
        }
示例#14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DBSemaphore"/> class.
 /// </summary>
 /// <param name="tablePrefix">The table prefix.</param>
 /// <param name="schedName">the scheduler name</param>
 /// <param name="defaultInsertSQL">The SQL.</param>
 /// <param name="defaultSQL">The default SQL.</param>
 /// <param name="dbProvider">The db provider.</param>
 protected DBSemaphore(
     string tablePrefix,
     string?schedName,
     string defaultSQL,
     string defaultInsertSQL,
     IDbProvider dbProvider)
 {
     Log              = LogProvider.GetLogger(GetType());
     this.schedName   = schedName;
     this.tablePrefix = tablePrefix;
     SQL              = defaultSQL;
     InsertSQL        = defaultInsertSQL;
     AdoUtil          = new AdoUtil(dbProvider);
 }
        private void LockViaInsert(ConnectionAndTransactionHolder conn, String lockName, String sql)
        {
            Log.DebugFormat("Inserting new lock row for lock: '{0}' being obtained by thread: {1}", lockName, Thread.CurrentThread.Name);
            using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, sql))
            {
                AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                if (cmd.ExecuteNonQuery() != 1)
                {
                    throw new DataException(
                              AdoJobStoreUtil.ReplaceTablePrefix("No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks + " for lock named: " + lockName, TablePrefix, SchedulerNameLiteral));
                }
            }
        }
        private async Task <bool> LockViaUpdate(
            Guid requestorId,
            ConnectionAndTransactionHolder conn,
            string lockName,
            string sql,
            CancellationToken cancellationToken)
        {
            using DbCommand cmd = AdoUtil.PrepareCommand(conn, sql);
            AdoUtil.AddCommandParameter(cmd, "schedulerName", SchedName);
            AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

            if (Log.IsDebugEnabled())
            {
                Log.DebugFormat("Lock '{0}' is being obtained: {1}", lockName, requestorId);
            }
            return(await cmd.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false) >= 1);
        }
示例#17
0
        private async Task LockViaInsert(ConnectionAndTransactionHolder conn, string lockName, string sql)
        {
            if (sql == null)
            {
                throw new ArgumentNullException(nameof(sql));
            }
            Log.DebugFormat("Inserting new lock row for lock: '{0}' being obtained by thread: {1}", lockName, Thread.CurrentThread.Name);
            using (var cmd = AdoUtil.PrepareCommand(conn, sql))
            {
                AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                if (await cmd.ExecuteNonQueryAsync().ConfigureAwait(false) != 1)
                {
                    throw new InvalidOperationException(
                              AdoJobStoreUtil.ReplaceTablePrefix("No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks + " for lock named: " + lockName, TablePrefix, SchedulerNameLiteral));
                }
            }
        }
示例#18
0
        /// <summary>
        /// Execute the SQL that will lock the proper database row.
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="lockName"></param>
        /// <param name="expandedSQL"></param>
        /// <param name="expandedInsertSQL"></param>
        protected override void ExecuteSQL(ConnectionAndTransactionHolder conn, string lockName, string expandedSQL, string expandedInsertSQL)
        {
            // attempt lock two times (to work-around possible race conditions in inserting the lock row the first time running)
            int count = 0;

            do
            {
                count++;
                try
                {
                    using (IDbCommand cmd = AdoUtil.PrepareCommand(conn, expandedSQL))
                    {
                        AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                        if (Log.IsDebugEnabled)
                        {
                            Log.DebugFormat("Lock '{0}' is being obtained: {1}", lockName, Thread.CurrentThread.Name);
                        }

                        int numUpdate = cmd.ExecuteNonQuery();

                        if (numUpdate < 1)
                        {
                            if (Log.IsDebugEnabled)
                            {
                                Log.DebugFormat("Inserting new lock row for lock: '{0}' being obtained by thread: {1}", lockName, Thread.CurrentThread.Name);
                            }
                            using (IDbCommand cmd2 = AdoUtil.PrepareCommand(conn, expandedInsertSQL))
                            {
                                AdoUtil.AddCommandParameter(cmd2, "lockName", lockName);

                                int res = cmd2.ExecuteNonQuery();

                                if (res != 1)
                                {
                                    if (count < 3)
                                    {
                                        // pause a bit to give another thread some time to commit the insert of the new lock row
                                        try
                                        {
                                            Thread.Sleep(TimeSpan.FromSeconds(1));
                                        }
                                        catch (ThreadInterruptedException)
                                        {
                                            Thread.CurrentThread.Interrupt();
                                        }
                                        // try again ...
                                        continue;
                                    }
                                    throw new Exception(AdoJobStoreUtil.ReplaceTablePrefix(
                                                            "No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks +
                                                            " for lock named: " + lockName, TablePrefix, SchedulerNameLiteral));
                                }
                            }

                            break; // obtained lock, no need to retry
                        }
                    }
                }
                catch (Exception sqle)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.DebugFormat("Lock '{0}' was not obtained by: {1}{2}", lockName, Thread.CurrentThread.Name, (count < 3 ? " - will try again." : ""));
                    }

                    if (count < 3)
                    {
                        // pause a bit to give another thread some time to commit the insert of the new lock row
                        try
                        {
                            Thread.Sleep(TimeSpan.FromSeconds(1));
                        }
                        catch (ThreadInterruptedException)
                        {
                            Thread.CurrentThread.Interrupt();
                        }
                        // try again ...
                        continue;
                    }

                    throw new LockException("Failure obtaining db row lock: " + sqle.Message, sqle);
                }
            } while (count < 2);
        }
示例#19
0
        /// <summary>
        /// Execute the SQL select for update that will lock the proper database row.
        /// </summary>
        protected override async Task ExecuteSQL(
            Guid requestorId,
            ConnectionAndTransactionHolder conn,
            string lockName,
            string expandedSql,
            string expandedInsertSql,
            CancellationToken cancellationToken)
        {
            Exception initCause = null;
            // attempt lock two times (to work-around possible race conditions in inserting the lock row the first time running)
            int count = 0;

            // Configurable lock retry attempts
            var maxRetryLocal    = MaxRetry;
            var retryPeriodLocal = RetryPeriod;

            do
            {
                count++;
                try
                {
                    using (DbCommand cmd = AdoUtil.PrepareCommand(conn, expandedSql))
                    {
                        AdoUtil.AddCommandParameter(cmd, "schedulerName", SchedName);
                        AdoUtil.AddCommandParameter(cmd, "lockName", lockName);

                        bool found;
                        using (var rs = await cmd.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false))
                        {
                            if (Log.IsDebugEnabled())
                            {
                                Log.DebugFormat("Lock '{0}' is being obtained: {1}", lockName, requestorId);
                            }

                            found = await rs.ReadAsync(cancellationToken).ConfigureAwait(false);
                        }

                        if (!found)
                        {
                            if (Log.IsDebugEnabled())
                            {
                                Log.DebugFormat("Inserting new lock row for lock: '{0}' being obtained by thread: {1}", lockName, requestorId);
                            }

                            using (DbCommand cmd2 = AdoUtil.PrepareCommand(conn, expandedInsertSql))
                            {
                                AdoUtil.AddCommandParameter(cmd2, "schedulerName", SchedName);
                                AdoUtil.AddCommandParameter(cmd2, "lockName", lockName);
                                int res = await cmd2.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);

                                if (res != 1)
                                {
                                    if (count < maxRetryLocal)
                                    {
                                        // pause a bit to give another thread some time to commit the insert of the new lock row
                                        await Task.Delay(retryPeriodLocal, cancellationToken).ConfigureAwait(false);

                                        // try again ...
                                        continue;
                                    }
                                    throw new Exception(AdoJobStoreUtil.ReplaceTablePrefix(
                                                            "No row exists, and one could not be inserted in table " + TablePrefixSubst + TableLocks +
                                                            " for lock named: " + lockName, TablePrefix));
                                }
                            }
                        }
                    }

                    // obtained lock, go
                    return;
                }
                catch (Exception sqle)
                {
                    if (initCause == null)
                    {
                        initCause = sqle;
                    }

                    if (Log.IsDebugEnabled())
                    {
                        Log.DebugFormat("Lock '{0}' was not obtained by: {1}{2}", lockName, requestorId, count < maxRetryLocal ? " - will try again." : "");
                    }

                    if (count < maxRetryLocal)
                    {
                        // pause a bit to give another thread some time to commit the insert of the new lock row
                        await Task.Delay(retryPeriodLocal, cancellationToken).ConfigureAwait(false);

                        // try again ...
                        continue;
                    }

                    throw new LockException("Failure obtaining db row lock: " + sqle.Message, sqle);
                }
            } while (count < maxRetryLocal + 1);

            throw new LockException("Failure obtaining db row lock, reached maximum number of attempts. Initial exception (if any) attached as root cause.", initCause);
        }
 public void Initialize(string tablePrefix, string schedName, AdoUtil adoUtil)
 {
     this.tablePrefix = tablePrefix;
     schedNameLiteral = "'" + schedName + "'";
     this.adoUtil = adoUtil;
 }
 /// <summary>
 /// Create new StdAdoDelegate instance.
 /// </summary>
 /// <param name="logger">the logger to use during execution</param>
 /// <param name="tablePrefix">the prefix of all table names</param>
 /// <param name="instanceId">The instance id.</param>
 /// <param name="dbProvider">The db provider.</param>
 /// <param name="useProperties">if set to <c>true</c> [use properties].</param>
 public StdAdoDelegate(ILog logger, string tablePrefix, string instanceId, IDbProvider dbProvider,
                       bool useProperties)
 {
     this.logger = logger;
     this.tablePrefix = tablePrefix;
     this.instanceId = instanceId;
     this.dbProvider = dbProvider;
     adoUtil = new AdoUtil(dbProvider);
     this.useProperties = useProperties;
 }
 public void Initialize(string tablePrefix, string schedName, AdoUtil adoUtil)
 {
     this.tablePrefix      = tablePrefix;
     this.schedNameLiteral = "'" + schedName + "'";
     this.adoUtil          = adoUtil;
 }