DEV Community

Cover image for Transacciones en laravel
Fernilo
Fernilo

Posted on

Transacciones en laravel

En ciertas ocasiones, necesitamos realizar una serie de operaciones consecutivas, y es fundamental que todas se completen con éxito, sin que ninguna quede a medias.

Un ejemplo común es la creación de un usuario, donde es esencial que también se asignen roles y se envíe un correo de registro.

Para manejar este tipo de situaciones, se utilizan las transacciones. A continuación, presentamos un método que crea un usuario, asigna el rol, y luego envía un correo a través del método sendEmail(). Este método recibe el correo electrónico como argumento y realiza el envío correspondiente.

use Illuminate\Support\Facades\DB;

public function save(array $data)
{
    try {
           $user = User::create($data);

           $user->syncRoles([$data['role']]);

           $this->sendEmail([
                'email' => $data['email'],
           ]);

            return $user;
   } catch (\Exception $e) {
          throw new BadRequestException("Error al guardar nuevo usuario");
   }
}
Enter fullscreen mode Exit fullscreen mode

Debemos aplicar 3 métodos:

  • DB::beginTransaction(); Inicia una transacción
  • DB::commit(); Confirma los cambios
  • DB::rollback(); En caso de que alguna operación no se pueda realizar revertirá todos los cambios haciendo que el estado sea el mismo a antes del inicio de la transacción.

Implementando transacciones en el código anterior nos queda:

use Illuminate\Support\Facades\DB;

public function save(array $data)
{
     // Iniciar la transacción
     DB::beginTransaction();
     try {

        $user = User::create($data);

        $user->syncRoles([$data['role']]);

        $this->sendEmail([
             'email' => $data['email'],
        ]);

        // Confirmo la transacción
        DB::commit();

        return $user;
     } catch (\Exception $e) {
        // Si falla hago rollback
        DB::rollback();

        throw new BadRequestException("Error al guardar nuevo usuario");
     }
 }
Enter fullscreen mode Exit fullscreen mode

Con esto nos aseguramos que el conjunto de operaciones se ejecuten completamente o no se ejecuten en absoluto.

Laravel también proporciona otro método mas concreto transaction de la fachada DB. En este caso el commit y el rollback se realizan de forma automática. Esto es recomendable cuando la cantidad de operaciones son pocas o no requiere operaciones adicionales antes de realizar el rollback

DB::transaction(function () use($data){

  $user = User::create($data);

  $user->syncRoles([$data['role']]);

  $this->sendEmail([
      'email' => $data['email'],
  ]);

  return $user;
});
Enter fullscreen mode Exit fullscreen mode

Importante: Consideraciones del motor de base de datos
No todos los motores de almacenamiento soportan transacciones. InnoDB es un motor que sí soporta transacciones, mientras que MyISAM no lo hace. Es fundamental asegurarse de que las tablas de la base de datos estén utilizando un motor que admita transacciones para que estas funcionen correctamente.

Top comments (1)

Collapse
 
programmerraja profile image
Boopathi

This is a great explanation of transactions in Laravel! I especially appreciate the clear examples and the section on database engine considerations.