简体   繁体   中英

Codeigniter how to use transactions

I have read up on some stuff about transactions in Codeigniter. I have implemented them in my code and was wondering if someone could take a look and see if I am going in the right direction? So far I have not encountered any database issues but I want to make sure I have implemented transactions correctly.

In my code, I create the user details first and get the ID, then I insert that ID into the user accounts table.

Controller

if($this->form_validation->run()==false){
            $this->index();
        }else{
            $password = md5($password);
            $package = array(
                'first_name'=>$first_name,
                'last_name'=>$last_name,
                'email'=>$email,
                'client_id'=>$client_id,
                'date_of_birth'=>$date_of_birth,
                'phone_number'=>$phone_number,
                'address'=>$address,
                'country'=>$country,
                'created_on'=>$this->get_date(),
                'updated_on'=>$this->get_date()
              );
            if($this->AccountModel->user_account_exists($email)){
                $this->session->set_flashdata('Error',"Account already exists");
                redirect('/Register');
            }else{
                $this->db->trans_start();
                $id = $this->AccountModel->create_person($package);
                $error = $this->db->error();
                $this->db->trans_complete();
                $expiration_date = date('Y-m-d', strtotime($this->get_date() . "+1 month") );
                if($this->db->trans_status()===false){
                    $this->index();
                }else{
                    $account = array(
                        'username'=>$email,
                        'password'=>$password,
                        'user_type'=>'user',
                        'person_id'=>$id,
                        'is_active'=>true,
                        'created_on'=>$this->get_date(),
                        'updated_on'=>$this->get_date(),
                        'expires_on'=>$expiration_date,
                        'status'=>'active'
                    );
                    $this->db->trans_start();
                    $id = $this->AccountModel->create_user_account($account);
                    $error = $this->db->error();
                    $this->db->trans_complete();
                    if($this->db->trans_status()===false){
                        $this->index();
                    }else{
                        $this->session->set_flashdata('Success','Account has been created');
                        redirect('/Login');
                    }
                }
            }
            if($error!=''){ 
              $this->session->set_flashdata('Error',$error["message"]);
              redirect('/Register');
            }
        }

Model

public function create_user_account($input){
        $this->db->insert('user_accounts',$input);
        return $this->db->insert_id();
    }

public function create_person($input){
        $this->db->insert('person',$input);
        return $this->db->insert_id();
    }

Hope someone can help me with this

The reason for transactions is to perform multiple db query operations and if any operations fail undo any that have already taken place.

You are only performing one operation within your transaction block so transactions are pointless. Other than that, you've got the idea.

In your case where you are only using db->insert() you can easily check the results and respond accordingly. db->insert() returns either true or false. If the return is false, get the error and set it into flashdata. Otherwise, go on with your work.

As @Topjka say, transactions should be in the model code.

Here's a sample model

class Some_model extends CI_Model
{
    public function save_stuff($data)
    {
        //let's assume $data has values for two different tables
        $newInfo = $data['newStuff'];
        $updateInfo = $data['oldStuff'];
        $this->db->trans_start();
        $this->db->insert('other_table', $newInfo);
        $this->db->update('one_table', $updateInfo);
        $this->db->trans_complete();
        if($this->db->trans_status() === FALSE)
        {
            $this->set_flash_error();
            return FALSE;  
        }
        return TRUE; //everything worked
    }

    public function set_flash_error()
    {
        $error = $this->db->error();
        $this->session->set_flashdata('Error', $error["message"]);
    }

}

Transactions are justified above because we do two db ops and if the either fails we don't want any changes to the db made.

Using the model/method in the controller

if($this->some_model->save_stuff($the_stuff) === FALSE)
{
    redirect('/wherever');
}
//All OK, proceed
//do other controller things

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM