Welcome Guest, Not a member yet? Register   Sign In
How to run Transactions in controller?
#1

I need to use transactions in my controller. My controller method is given below. This is not working and should not be as far as I understand. So, what could be the solution? Again, is it good practice to use transactions in the controller?

Thank you in advance.

PHP Code:
public function add_payment(){
    if(
$this->request->getMethod() != 'post') return redirect()->back();
    if(!
$this->validate('addOrderPayment')) session()->setFlashdata('error'$this->validator->listErrors());
    else{
        
$oid $this->request->getPost('oid');
        if(
$this->request->getPost('odrTkn') === md5(session('token').$oid)){
            
$order = (new ODR(['gid'=> esc($oid)]))->getOrder();
            
$data = [
                
'amount'=> $this->request->getPost('amount')
            ];
            
            
$db = \Config\Database::connect(); 
            
$db->transStart();
            
service('transaction')->addTrx($data);
            
service('order')->balanceDue($oid$data['amount']);
            
$db->transComplete();
            if (
$db->transStatus() === FALSE){
                
$this->db->transRollback();
                
session()->setFlashdata('error''Something went wrong!!');
            }
            else{
                
$db->transCommit();
                
session()->setFlashdata('success''Payment added successfully!!');
            }
        }else 
session()->setFlashdata('error''Invalid request!!');
    }
    return 
redirect()->back();


Quote:The output is always the same:
Payment added successfully!!

Thank you in advance.
"Who thinks in code"
Perfectly describes who I am
mbparvez.me
Reply
#2

Transactions should be handled in the Model that's where your business logic should be.

Initializing the database and accessing it in the controller is breaking the mvc logic.

Make methods in your model for this then call that method from the controller.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

(This post was last modified: 04-03-2021, 05:20 AM by yahyaerturan. Edit Reason: Use coding block this time. )

(04-02-2021, 06:01 AM)InsiteFX Wrote: Transactions should be handled in the Model that's where your business logic should be.

Initializing the database and accessing it in the controller is breaking the mvc logic.

Make methods in your model for this then call that method from the controller.

I am not sure if it is the best practice but if not I want to learn the correct way Smile

I think it should be handled in controller for the following reasons:

- In a controller endpoint it can be used methods from different models which we want all to be in same transaction. For example, adding new tags to article when adding a new article, or adding new product tags when adding a new product.
- Sending response from API endpoint if transaction fails.

Here is an example how I use it:

PHP Code:
/**
* @method POST
* @url /api/{version}/company
*/
public function create(): ResponseInterface
{
    $createData $this->request->getJSON();

    $this->db->transStart();

    $tagIds $this->handleIndustries($createData); // Adding new industries

    $isSaved $this->model->save($createData);

    if (false === $isSaved) {
        return $this->failValidation($this->model->errors(), Domain::COMPANY);
    }

    $insertID $this->model->getInsertID();

    if (false === $qB->addOrUpdateRelations($tagIds$insertID)) {
        return $this->failPersistence(
            'One or more relation(s) could not be saved.',
            Domain::COMPANY_INDUSTRY);
    }

    $this->db->transComplete();

    if (false === $this->db->transStatus()) {
        return $this->failPersistence(
            'An error occurred in transaction.',
            Domain::COMPANY
        
);
    }

    $data $this->model->find($insertID);

    return $this->respondCreated($data);




If there is a better way, I'd like to learn..
Reply
#4

Add this to your BaseController in the "Preload" section of the initController method:

PHP Code:
$this->db = \Config\Database::connect(); //Load database connection 

You should then be able to use transactions in any Controller like this:

PHP Code:
$this->db->transStart(); //Begin database transaction
$this->db->transComplete(); //Complete database transaction 
Reply
#5

(04-06-2021, 09:44 AM)mlurie Wrote: Add this to your BaseController in the "Preload" section of the initController method:

PHP Code:
$this->db = \Config\Database::connect(); //Load database connection 

You should then be able to use transactions in any Controller like this:

PHP Code:
$this->db->transStart(); //Begin database transaction
$this->db->transComplete(); //Complete database transaction 

Creating the object in the BaseController has been deprecated.  Use this instead in your model or controller:

PHP Code:
$db = \Config\Database::connect(); //Load database connection

$db->transStart(); //Begin database transaction
$db->transComplete(); //Complete database transaction 
Reply




Theme © iAndrew 2016 - Forum software by © MyBB