execute = (ctx, obj, isTX, config) => {

    const $p = config.promise;

    // updates the task context and notifies the client;
    function update(start, success, result) {
        const c = ctx.ctx;
        if (start) {
            npm.utils.addReadProp(c, 'start', new Date());
        } else {
            c.finish = new Date();
            c.success = success;
            c.result = result;
            c.duration = c.finish - c.start;
        }
        (isTX ? Events.transact : Events.task)(ctx.options, {
            client: ctx.db && ctx.db.client, // loss of connectivity is possible at this point
            dc: ctx.dc,
            ctx: c
        });
    }

    let cbData, cbReason, success,
        spName; // Save-Point Name;

    const capSQL = ctx.options.capSQL; // capitalize sql;

    update(true);

    if (isTX) {
        // executing a transaction;
        spName = `sp_${ctx.txLevel}_${ctx.nextTxCount}`;
        return begin()
            .then(() => callback(ctx, obj, ctx.cb, config)
                .then(data => {
                    cbData = data; // save callback data;
                    success = true;
                    return commit();
                }, err => {
                    cbReason = err; // save callback failure reason;
                    return rollback();
                })
                .then(() => {
                    if (success) {
                        update(false, true, cbData);
                        return cbData;
                    }
                    update(false, false, cbReason);
                    return $p.reject(cbReason);
                },
                err => {
                    // either COMMIT or ROLLBACK has failed, which is impossible
                    // to replicate in a test environment, so skipping from the test;
                    // istanbul ignore next:
                    update(false, false, err);
                    // istanbul ignore next:
                    return $p.reject(err);
                }),
            err => {
                // BEGIN has failed, which is impossible to replicate in a test
                // environment, so skipping the whole block from the test;
                // istanbul ignore next:
                update(false, false, err);
                // istanbul ignore next:
                return $p.reject(err);
            });
    }

    function begin() {
        if (!ctx.txLevel && ctx.mode instanceof npm.mode.TransactionMode) {
            return exec(ctx.mode.begin(capSQL), 'savepoint');
        }
        return exec('begin', 'savepoint');
    }

    function commit() {
        return exec('commit', 'release savepoint');
    }

    function rollback() {
        return exec('rollback', 'rollback to savepoint');
    }

    function exec(top, nested) {
        if (ctx.txLevel) {
            return obj.none((capSQL ? nested.toUpperCase() : nested) + ' ' + spName);
        }
        return obj.none(capSQL ? top.toUpperCase() : top);
    }

    // executing a task;
    return callback(ctx, obj, ctx.cb, config)
        .then(data => {
            update(false, true, data);
            return data;
        })
        .catch(error => {
            update(false, false, error);
            return $p.reject(error);
        });
}
@private
@method Task.execute
Executes a task.

@param ctx
@param obj
@param isTX
@param config
@returns {Promise.<TResult>}