# Buggy code
def mass_action(self, querylist=None, logTransaction=False, fetchall=False):
    """
    Execute multiple queries

    :param querylist: list of queries
    :param logTransaction: Boolean to wrap all in one transaction
    :param fetchall: Boolean, when using a select query force returning all results
    :return: list of results
    """
    # Remove Falsey types
    querylist = (q for q in querylist or [] if q)

    sql_results = []
    attempt = 0

    with db_locks[self.filename]:
        self._set_row_factory()
        while attempt < 5:
            try:
                for qu in querylist:
                    if len(qu) == 1:
                        if logTransaction:
                            logger.log(qu[0], logger.DEBUG)
                        sql_results.append(self._execute(qu[0], fetchall=fetchall))
                    elif len(qu) > 1:
                        if logTransaction:
                            logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG)
                        sql_results.append(
                            self._execute(qu[0], qu[1], fetchall=fetchall)
                        )
                self.connection.commit()
                logger.log(
                    "Transaction with " + str(len(sql_results)) + " queries executed",
                    logger.DEBUG,
                )

                # finished
                break
            except sqlite3.OperationalError as e:
                sql_results = []
                if self.connection:
                    self.connection.rollback()
                if (
                    "unable to open database file" in e.args[0]
                    or "database is locked" in e.args[0]
                ):
                    logger.log("DB error: " + ex(e), logger.WARNING)
                    attempt += 1
                    time.sleep(1)
                else:
                    logger.log("DB error: " + ex(e), logger.ERROR)
                    raise
            except sqlite3.DatabaseError as e:
                sql_results = []
                if self.connection:
                    self.connection.rollback()
                logger.log("Fatal error executing query: " + ex(e), logger.ERROR)
                raise

        # time.sleep(0.02)

        return sql_results


# Traceback (OperationalError)
2017-10-28 14:56:23 DEBUG    SEARCHQUEUE-FORCED-71712 :: [BITHDTV] :: [42b1e5f] Traceback (most recent call last):
  File "/home/pi/Medusa/medusa/search/core.py", line 555, in search_providers
    down_cur_quality, manual_search, manual_search_type)
  File "/home/pi/Medusa/medusa/providers/generic_provider.py", line 428, in find_search_results
    db.mass_action(cl)
  File "/home/pi/Medusa/medusa/db.py", line 223, in mass_action
    self.connection.rollback()
OperationalError: cannot rollback - no transaction is active
2017-10-28 14:56:23 ERROR    SEARCHQUEUE-FORCED-71712 :: [BITHDTV] :: [42b1e5f] Unknown exception while searching BITHDTV. Error: 'cannot rollback - no transaction is active'
Traceback (most recent call last):
  File "/home/pi/Medusa/medusa/search/core.py", line 555, in search_prov2017-10-28 16:05:06 DEBUG    DAILYSEARCHER :: [42b1e5f] Started updating network timezones

# Fixed code
def mass_action(self, querylist=None, logTransaction=False, fetchall=False):
    """
    Execute multiple queries

    :param querylist: list of queries
    :param logTransaction: Boolean to wrap all in one transaction
    :param fetchall: Boolean, when using a select query force returning all results
    :return: list of results
    """
    # Remove Falsey types
    querylist = (q for q in querylist or [] if q)

    sql_results = []
    attempt = 0

    with db_locks[self.filename]:
        self._set_row_factory()
        while attempt < 5:
            try:
                for qu in querylist:
                    if len(qu) == 1:
                        if logTransaction:
                            logger.log(qu[0], logger.DEBUG)
                        sql_results.append(self._execute(qu[0], fetchall=fetchall))
                    elif len(qu) > 1:
                        if logTransaction:
                            logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG)
                        sql_results.append(
                            self._execute(qu[0], qu[1], fetchall=fetchall)
                        )
                self.connection.commit()
                logger.log(
                    "Transaction with " + str(len(sql_results)) + " queries executed",
                    logger.DEBUG,
                )

                # finished
                break
            except sqlite3.OperationalError as e:
                sql_results = []
                self._try_rollback()
                if (
                    "unable to open database file" in e.args[0]
                    or "database is locked" in e.args[0]
                ):
                    logger.log("DB error: " + ex(e), logger.WARNING)
                    attempt += 1
                    time.sleep(1)
                else:
                    logger.log("DB error: " + ex(e), logger.ERROR)
                    raise
            except sqlite3.DatabaseError as e:
                sql_results = []
                self._try_rollback()
                logger.log("Fatal error executing query: " + ex(e), logger.ERROR)
                raise

        # time.sleep(0.02)

        return sql_results