mysqli上的数据库抽象层

when trying to build robust database code (table locking, transactions, etc) i am always annoyed by the mass of code that needs to be done.

For example a transaction out of two prepared statements where i want to delete a user and update something about him in an "actions" table:

  1. Lock Table users, actions
  2. Start a transaction (autocommit false)
  3. Make a prepared statement for the deletion of a user
  4. Check if statement is != false (cause it could have already failed at 3.
  5. Bind param
  6. Check errorState != "00000" on the statement (can also have failed at binding params)
  7. execute statement
  8. Check errorState != "00000" on the statement (can also have failed at executing)
  9. get Result of statement
  10. Close statement
  11. Make a new prepared statement for update actions
  12. Check if statement != false
  13. bind params
  14. check statement's errorState
  15. execute
  16. check statement's errorState
  17. get result
  18. close statement
  19. check overall transaction state, if valid commit, if not valid rollback
  20. unlock tables
  21. set autocommit back to true

This is how i do it (maybe im doing it wrong?). And if i do it that way its a lot of work and annoying. So i thought automateing that stuff.

What i want is something like this:

$DB->startTransaction();
$DB->query($query);
$DB->query($query2);
$DB->query($query3);
$DB->endTransaction();

And internally the database abstraction layer ontop of mysqli will take care of table locking, prepared statements and transactions itself. Shouldn't we be able to automate this?

This is one of my attempts:

public function query($query, $table, $params = null) {
            if($params == null) {
                $this->connection->query("LOCK TABLES $table WRITE");
                $query = str_replace("!", $table, $query);
                $result = $this->connection->query($query);
                $this->connection->query("UNLOCK TABLES");
                return $result;
            }
            else {
                if (!$this->checkParams($query, $params)) {
                    return false;
                }
                $this->connection->query("LOCK TABLES $table WRITE");
                $query = str_replace("!", $table, $query);

                $stmt = $this->connection->prepare($query);
                if ($stmt != false) {
                    $typesString = "";
                    foreach ($params as $param) {
                        if (is_numeric($param)) {
                            $typesString .= "i";
                        } else if (is_double($param)) {
                            $typesString .= "d";
                        } else {
                            $typesString .= "s";
                        }
                    }

                    $finalParamArray = array($typesString);
                    $finalParamArray = array_merge($finalParamArray, $params);
                    call_user_func_array(array($stmt, "bind_param"), $this->ref($finalParamArray));
                    $this->checkStatement($stmt);
                    $stmt->execute();
                    $this->checkStatement($stmt);
                    $result = $stmt->get_result();
                    $stmt->close();
                    $this->connection->query("UNLOCK TABLES");
                    return $result;
                }
                $this->query("UNLOCK TABLES");
                return false;
            }
        }

This would be callable like this:

$DB->query("DELETE FROM ! WHERE userID =?", "Users", array($userID));

I am however not feeling confident about this. I googled a bit and didn't find something like i want. So my question now is: Is something like i want actually possible (well it should be)? Am i doing it wrong?

EDIT: I also have 2 other attempts of doing this, which look MUCH MORE complicated (300+ lines of code). I can post them as well, if you want. I am still however not satisfied with them and not confident if this is actually correct!