constructor(options) {
        options = assert(options, ['tiLevel', 'deferrable', 'readOnly']);
        const {readOnly, deferrable} = options;
        let {tiLevel} = options;
        let level, accessMode, deferrableMode, begin = 'begin';
        tiLevel = (tiLevel > 0) ? parseInt(tiLevel) : 0;

        if (tiLevel > 0 && tiLevel < 4) {
            const values = ['serializable', 'repeatable read', 'read committed'];
            level = 'isolation level ' + values[tiLevel - 1];
        }
        if (readOnly) {
            accessMode = 'read only';
        } else {
            if (readOnly !== undefined) {
                accessMode = 'read write';
            }
        }
        // From the official documentation: http://www.postgresql.org/docs/9.5/static/sql-set-transaction.html
        // The DEFERRABLE transaction property has no effect unless the transaction is also SERIALIZABLE and READ ONLY
        if (tiLevel === isolationLevel.serializable && readOnly) {
            if (deferrable) {
                deferrableMode = 'deferrable';
            } else {
                if (deferrable !== undefined) {
                    deferrableMode = 'not deferrable';
                }
            }
        }
        if (level) {
            begin += ' ' + level;
        }
        if (accessMode) {
            begin += ' ' + accessMode;
        }
        if (deferrableMode) {
            begin += ' ' + deferrableMode;
        }

        super({begin, capBegin: begin.toUpperCase()});
    }
@class txMode.TransactionMode
@description
Constructs a complete transaction-opening `BEGIN` command, from these options:
 - isolation level
 - access mode
 - deferrable mode

The type is available from the {@link txMode} namespace.

@param {} [options]
Transaction Mode options.

@param {txMode.isolationLevel} [options.tiLevel]
Transaction Isolation Level.

@param {boolean} [options.readOnly]
Sets transaction access mode based on the read-only flag:
 - `undefined` - access mode not specified (default)
 - `true` - access mode is set to `READ ONLY`
 - `false` - access mode is set to `READ WRITE`

@param {boolean} [options.deferrable]
Sets transaction deferrable mode based on the boolean value:
 - `undefined` - deferrable mode not specified (default)
 - `true` - mode is set to `DEFERRABLE`
 - `false` - mode is set to `NOT DEFERRABLE`

It is used only when `tiLevel`=`isolationLevel.serializable`
and `readOnly`=`true`, or else it is ignored.

@returns {txMode.TransactionMode}

@see $[BEGIN], {@link txMode.isolationLevel}

@example

const {TransactionMode, isolationLevel} = pgp.txMode;

// Create a reusable transaction mode (serializable + read-only + deferrable):
const mode = new TransactionMode({
    tiLevel: isolationLevel.serializable,
    readOnly: true,
    deferrable: true
});

db.tx({mode}, t => {
    return t.any('SELECT * FROM table');
})
    .then(data => {
        // success;
    })
    .catch(error => {
        // error
    });

// Instead of the default BEGIN, such transaction will start with:

// BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE