Monday, 3 December 2018

CodeIgniter Transactions - trans_status and trans_complete return true but nothing being committed

Problem:

I have written a function in my model to insert an order into my database. I am using transactions to make sure that everything commits or else it will be rolled back. My problem is that CodeIgniter is not showing any database errors, however it is rolling back the transaction but then returning TRUE for trans_status.

I am currently using CodeIgniter 3.19, PHP (7.2), and mySQL (5.7), Apache 2.4.

The function logic works as such:

  • Inserts the order array into tbl_orders
  • Saves order_id, and goes through each of the order products (attaches order_id) and inserts the product in tbl_order_products,
  • Saves order_product_id and attaches it to an array of users attendance options and inserts that into tbl_order_attendance
  • Takes the payment transaction array (attaches the order_id) and inserts that into tbl_transactions
  • IF there is a discount on the order, it decreases the discount_redeem_count (number of redeemable discount codes) by 1.

Actual Function

Here is the actual function (I have reduced a little so you get the idea):

public function add_order($order, $order_products, $transaction){
    $this->db->trans_start();

    $this->db->insert('tbl_orders', $order);
    $order_id = $this->db->insert_id();

    foreach($order_products as $key=>$value){
        $order_product[$key]['order_id'] = $order_id;
        $this->db->insert('tbl_order_products', $order_products);
        $order_product_id = $this->db->insert_id();

        // use order_product_id to create attendance array

        $this->db->insert('tbl_order_product_attendance', $order_product_attendance);
    }

    if(!empty($transaction){
        $transaction['order_id'] = $order_id;
        $this->db->insert('tbl_transactions', $transaction);
        $transaction_id = $this->db->insert_id();
    }

    $discount = $order->get_discount();

    if(!empty($discount)){
        $this->db->set('discount_redeem_count', 'discount_redeem_count-1', false);
        $this->db->where('discount_id', $discount['discount_id']);
        $this->db->update('tbl_discounts');
    }

    $this->db->trans_complete();

    if($this->db->trans_status() !== false){
        $result['outcome'] = true;
        $result['insert_id'] = $order_id;
        return $result;
    }else{
        $result['outcome'] = false;
        return $result;
    }
}

When this function completes, both trans_complete and trans_status return TRUE. However the transaction is never committed.

What I've tried:

  • I have dumped the contents of $this->db->error() after each query and there are no errors in any of the queries.

  • I have used this->db->last_query() to print out each query and then checked the syntax online to see if there were any problems, there were none.

  • I have tried echoing all of the return insert_ids and they all work (However I can't test the last one because it's an UPDATE query)

  • I also tried changing to using CodeIgniters Manual Transactions like:

EXAMPLE:

$this->db->trans_begin();
 // all the queries
if($this->db->trans_status() !== false){
    $this->db->trans_commit();
    $result['outcome'] = true;
    $result['insert_id'] = $order_id;
    return $result;
}else{
    $this->db->trans_rollback();
    $result['outcome'] = false;
    return $result;
}

  • I have tried submitting an order that doesn't have a discount and the entire process works! Which leads me to believe that my problem is with my UPDATE query. I just cannot see what the issue is.

If you have an idea that I haven't tried yet, or need more information from me, please comment and I will reply promptly.

Question:

Why does trans_status return TRUE if none of my transaction is being committed?


Edit 1:

I have gone through the Codeigniter log files (at a log_threshold = 4) as well and there is nothing to suggest a rollback happened. However, the order_id is still being stored into the $order_id variable before the rollback happens and can be echoed, as well as the order_product_id and the transaction_id. That is why I think that that the problem has something to do with the last UPDATE query.



from CodeIgniter Transactions - trans_status and trans_complete return true but nothing being committed

No comments:

Post a Comment