MySQLi Transaction Spaghetti Hell

I have a class with more than a hundred functions/methods in it. Many of them require to run MySQLi query within a transaction. So, in a simple form, most of the functions look like this:

class MyClass {
    private $connection = ...; // mysqli connection
    public function a () {
        $this->connection->autocommit(FALSE);
        // do something and run multiple queries
        $this->connection->commit();
    }
    public function b () {
        $this->connection->autocommit(FALSE);
        // do something and run multiple queries
        $this->connection->commit();
    }
}
// to run the code:
$myclass = new MyClass();
$myclass->a(); // all queries are run inside a transaction
$myclass->b(); // all queries are run inside a transaction

The concept is simple: Every time I run a public function/method, it starts a transaction and commits before ending the function/method. Now, my problem is... what if I want to run a method within another method, while keeping both methods public and callable by callers outside the class??? For example:

class MyClass {
    private $connection = ...; // mysqli connection
    public function a () {
        $this->connection->autocommit(FALSE);
        // do something and run multiple queries
        $this->connection->commit();
    }
    public function b () {
        $this->connection->autocommit(FALSE);
        // do something and run multiple queries
        $this->a(); // running function a inside function b here
        $this->connection->commit();
    }
}
// to run the code:
$myclass = new MyClass();
$myclass->a(); // all queries are run inside a transaction
$myclass->b(); // transaction is not working as I initially wished. This function consists of more than one commit, hence, not everything is run inside one transaction

Using extra variables for manual if/else checking, I suppose I can solve the problem above with two functions. However, my problem here is that I have multiple, possibly nearly a hundred, functions/methods that act like the above. I don't think I can use a few if/else to handle such complicated problem of transaction spaghetti hell.

How might I resolve this?

P.S:

The above is just a simplification of my class. To make things even more complicated, in my class I didn't just use:

function func() {
    $this->connection->autocommit(FALSE);
    // do something
    $this->connection->commit();
}

Instead, I did something like this:

function func() {
    if ($result = $this->connection->query('SELECT @@autocommit')) {
        $row = mysqli_fetch_row($result);
        $originalAutoCommitValue = $row[0];
        mysqli_free_result($result);
    }
    if (!$originalAutoCommitValue) {
        $this->connection->autocommit(FALSE);
    }
    // do something...
    $this->connection->commit();
    $this->connection->autocommit($originalAutoCommitValue);
}

This will allow the function/method in my class to start a transaction, commit the transaction and return the auto commit state back to before. This is really clumsy, but I hope that the users of my class have their choice of whether to use transaction/commit outside the class. I hope this approach will not affect their original state of auto commit before using any of my class' methods.

UPDATE

I have added the following properties and two functions in the class:

private $connectionTransactionStack = 0;
private $connectionOriginalAutoCommitState = NULL;

private function startTransaction() {
    if (is_null($this->connectionOriginalAutoCommitState)) {
        if ($result = $this->connection->query('SELECT @@autocommit')) {
            $row = mysqli_fetch_row($result);
            $this->connectionOriginalAutoCommitState = $row[0];
            mysqli_free_result($result);
        }
    }
    if ($this->connectionOriginalAutoCommitState === 1) {
        $this->connection->autocommit(FALSE);
    }
    $this->connectionTransactionStack++;
}
private function commitTransaction() {
    $this->connectionTransactionStack--;
    if ($this->connectionTransactionStack < 1) {
        $this->connectionTransactionStack = 0;
        if ($this->connectionOriginalAutoCommitState === 1) {
            $this->connection->commit();
            $this->connection->autocommit($this->connectionOriginalAutoCommitState);
        }
    }
}

So, now when I want to run original functions, I can just do this:

class MyClass {

    public function a () {
        $this->startTransaction();
        // do something and run multiple queries
        $this->commitTransaction();
    }
    public function b () {
        $this->startTransaction();
        // do something and run multiple queries
        $this->a(); // running function a inside function b here
        $this->commitTransaction();
    }
}

As long as I commit all transactions if I started any in any methods, the non-final $this->commitTransaction() will not run a real mysqli->commit(), but the final $this->commitTransaction() will run mysqli->commit if necessary (depending on the initial state before the first run any methods inside my class). So if I want to run:

$this->a();

or

$this->b();

, it doesn't matter at all because there is a stack to count the transaction I would have started. However, in real, there is only one transaction to be started and committed.

Would this be a solution to my problem above?

One option might be to delete:

$this->connection->autocommit(FALSE);
$this->connection->commit();

in every function that is relevant (a,b) and then wrap them around your function calls.

class MyClass {
    private $connection = ...; // mysqli connection
    public function a () {
        // do something and run multiple queries
    }
    public function b () {
        // do something and run multiple queries
        $this->a(); // running function a inside function b here
    }
}
// to run the code:
$myclass = new MyClass();

$myclass->connection->autocommit(FALSE);
$myclass->a(); // all queries are run inside a transaction
$myclass->b(); 
$this->connection->commit();

UPDATE:

OR maybe better , use a wrapper-function for calling the functions inside the class:

$myclass->doTransaction('a'); 
$myclass->doTransaction('b'); 

function doTransaction($functionCall) {
    //Do some sanitizing of the functionCall-variable
    $this->connection->autocommit(FALSE);
    call_use_func($functionCall); 
    $this->connection->commit();
}