rublopweb's avatar

updating and creating models

Hi, i have a function that calls another function i a condition is fulfilled and makes some database operations and i am looking the best approach to manage the integrity of the operations. The function are these ones:

public function store(array $attributes){

	.....
	if ($shouldBePaid) $this->desactivatePrevious($payments)

	  DB::beginTransaction();
        
        try {    
            $new_model = Model::create($attributes); 
            DB::commit();
        } catch (Exception $e) {
            DB::rollBack();
        }
}

private function desactivatePrevious (Collection $payments){

	$payments->each(function(Payment $payment){
		$payment->status=0;
		$payment->save();
}
}

i have been testing the code and i want to avoid that if there is an exception in the main function and the model can not be created, the status of the other model are updated. How should i do it? Thanks,

0 likes
3 replies
LaryAI's avatar
Level 58

It looks like you want to ensure that the desactivatePrevious operation and the creation of a new model are both done within the same database transaction to maintain data integrity. To achieve this, you should move the DB::beginTransaction() call to before the desactivatePrevious method is called and ensure that both operations are within the try block. Here's how you can modify your code:

public function store(array $attributes)
{
    DB::beginTransaction();
    
    try {
        if ($shouldBePaid) {
            $this->desactivatePrevious($payments);
        }

        $new_model = Model::create($attributes); 
        DB::commit();
    } catch (Exception $e) {
        DB::rollBack();
        // Handle the exception, e.g., log it or return an error response
        throw $e;
    }
}

private function desactivatePrevious(Collection $payments)
{
    $payments->each(function (Payment $payment) {
        $payment->status = 0;
        $payment->save();
    });
}

In this updated code, the transaction begins before any database operations. If an exception is thrown during either the desactivatePrevious method or the model creation, the transaction will be rolled back, and none of the changes will be applied to the database. This ensures that your database operations are atomic and that you won't end up with only part of the operations being applied.

Remember to pass the $payments collection and the $shouldBePaid variable to the store method if they are not already available within its scope. Also, make sure to handle the exception appropriately after rolling back the transaction, which might include logging the error or returning an error response to the user.

Snapey's avatar

Why would the model not be created?

Why use a transaction? Either the create works or it doesn't If an exception is thrown then the database state will be unchanged anyway.

Please can you check the wording of your question. You say that if there is an issue with the create then the status of the other model are updated, but you are updating the other model before and independently of the create so they will be updated in all circumstances.....

1 like
rublopweb's avatar

Yes, I mean that the modification of the other models should not be independent of the creation of the main model and i want that if the creation of the model fails, the status of the other models should not be updated.

1 like

Please or to participate in this conversation.