how can do nested laravel transaction

I am using laravel to store records and other operations. My code is:

public function store(Request $request)
{ 
    DB::beginTransaction();
    try {
    
    // Start step 1
    if($request->steps == 'step1')
    {
        $filteredKeywords = array_filter($request->keywords, function ($value) {
            // Remove null values from the array
            return $value !== null;
        });
        $uniquen_number = $this->generateUniqueNumber();
        $videoupload = new Videoupload();
        $videoupload->user_id = Auth::id();
        $videoupload->unique_number = $uniquen_number;
        $videoupload->videostatus_id = 1;
        $videoupload->videotype_id = $request->videotype_id;
        $videoupload->videosubtype_id = $request->videosubtype_id;
        $videoupload->majorcategory_id = $request->majorcategory_id;
        $videoupload->subcategory_id = json_encode($request->subcategory_id);
        $videoupload->video_title = $request->video_title;
        $videoupload->keywords = json_encode($filteredKeywords);
        $videoupload->references = $request->references;
        $videoupload->abstract = $request->abstract;
        $videoupload->declaration_of_interests1 = $request->declaration_of_interests;
        $videoupload->acknowledge = $request->acknowledge;
        $videoupload->doi_link = $request->doi_link;
        if($videoupload->declaration_of_interests1 == 2)
        {
            $videoupload->declaration_remark = $request->declaration_remark;
        }  
        $videoupload->membershipplan_id = $request->membershipplan_id;
        $videoupload->terms_n_conditions = $request->terms_n_conditions;
        $videoupload->save();
        return response()->json(['success'=>'progress','steps'=>'step2','videoid'=>$videoupload->id,'message' => 'm1']);
    }
    // End step 1

    if($request->hasFile('vide_Upload')){

        // Start step 2
        if($request->steps == 'step2')
        {
            $video_details_step2 = single_video_details_without_join($request->videoid);
            $uniquen_number = $video_details_step2->unique_number;
            $major_category_details = get_majorcategories($request->majorcategory_id);
            $folderName = str_replace(' ', '_', $major_category_details->category_name);
            $vide_Upload2_image = $request->file('vide_Upload');
            $extension = $vide_Upload2_image->getClientOriginalExtension();
            $newFileName = $uniquen_number . '.' . $extension;
            $filePath = $vide_Upload2_image->storeAs('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number, $newFileName, 'public');
            $video_path_url = asset(Storage::url($filePath));

            $video_upload_step2 = Videoupload::find($request->videoid);
            $video_upload_step2->full_video_url = $video_path_url;
            $video_upload_step2->main_folder_name = 'Videos_to_Revise';
            $video_upload_step2->category_folder_name = $folderName;
            $video_upload_step2->uploaded_video = $newFileName;
            $video_upload_step2->save();
            DB::commit();
            return response()->json(['success'=>'progress','steps'=>'step3','videoid'=>$request->videoid,'message' => 'm2']);
        }

        if($request->steps == 'step3')
        {
            $video_details_step3 = single_video_details_without_join($request->videoid);
            $folderName = $video_details_step3->category_folder_name;
            $uniquen_number = $video_details_step3->unique_number;
            $newFileName = $video_details_step3->uploaded_video;

            $vide_Upload2_image_step3 = $request->file('vide_Upload');
            $extension_step3 = $vide_Upload2_image_step3->getClientOriginalExtension();
            $newFileName_cropped_file = $uniquen_number . '_cropped.' . $extension_step3;
        // Start crop the video
            $video_path = storage_path('app/public/uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number.'/'.$newFileName);
            $croppedVideoPath = storage_path('app/public/uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number.'/'.$newFileName_cropped_file);
            $cropped_video_path_url = url('/storage/uploads/Videos_to_Revise/' . $folderName.'/'.$uniquen_number . '/' . $newFileName_cropped_file);
        
            //$ffmpegCommand = "C:/FFmpeg/bin/ffmpeg -i " . $video_path . " -ss 00:00:00 -t 00:00:20 " . $croppedVideoPath;
            $ffmpegCommand = "ffmpeg -i " . $video_path . " -ss 00:00:00 -t 00:00:45 " . $croppedVideoPath;
            $test = exec($ffmpegCommand);

            $video_upload_step3 = Videoupload::find($request->videoid);
            $video_upload_step3->short_video_url = $cropped_video_path_url;
            $video_upload_step3->save();
        // End crop the video
        return response()->json(['success'=>'progress','steps'=>'step4','videoid'=>$request->videoid,'message' => 'm3']);
        }

        if($request->steps == 'step4')
        {
            $video_details_step4 = single_video_details_without_join($request->videoid);
            $folderName = $video_details_step4->category_folder_name;
            $uniquen_number = $video_details_step4->unique_number;
            $newFileName = $video_details_step4->uploaded_video;                

            $vide_Upload2_image_step4 = $request->file('vide_Upload');
            $extension_step4 = $vide_Upload2_image_step4->getClientOriginalExtension();
            $newFileName_cropped_file = $uniquen_number . '_cropped.' . $extension_step4;

            $filePath = 'uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number.'/'.$newFileName;
        // start encrypting the videos
        $highBitrate = (new X264)->setKiloBitrate(1000);
        //start encrypting fulllength files
        FFMpeg::fromDisk('public')
            ->open($filePath) // Provide the path relative to the 'local' disk
            ->exportForHLS()
            ->withRotatingEncryptionKey(function ($filename, $contents) use ($folderName,$uniquen_number) {
                Storage::disk('public')->put('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number . '/encrypted_files/' . $filename, $contents);
            })
            ->addFormat($highBitrate)
            ->save('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number . '/encrypted_files/'.$uniquen_number.'.m3u8');
        //end encrypting fulllength files
        //start encrypting cropped files
        FFMpeg::fromDisk('public')
            ->open('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number.'/'.$newFileName_cropped_file) // Provide the path relative to the 'local' disk
            ->exportForHLS()
            ->withRotatingEncryptionKey(function ($filename, $contents) use ($folderName,$uniquen_number) {
                Storage::disk('public')->put('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number . '/encrypted_files/' . $filename, $contents);
            })
            ->addFormat($highBitrate)
            ->save('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number . '/encrypted_files/'.$uniquen_number.'_cropped.m3u8');

        FFMpeg::fromDisk('public')
            ->open('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number.'/'.$newFileName_cropped_file) // Provide the path relative to the 'local' disk
            ->getFrameFromSeconds(3)
            ->export()
            ->save('uploads/Videos_to_Revise/'.$folderName.'/'.$uniquen_number . '/'.$uniquen_number.'_screenshot.webp');
        //end encrypting cropped files
        // end encrypting the videos
        return response()->json(['success'=>'progress','steps'=>'step5','videoid'=>$request->videoid,'message' => 'm4']);
        }
    }
    //$videoupload->save();
    if($request->steps == 'step5')
    {
        $video_details_step5 = single_video_details_without_join($request->videoid);
        // Assuming $data is the array you provided
        $data = $request->name;

        $user_details = User::find(Auth::id());
        $user_details->role_id = 2; // Change role from member to author
        $user_details->save();

        $check_role = Userrole::where('user_id',Auth::id())->where('role_id',2)->first(); 
        // 2 means author       
        if(empty($check_role))
        {
            $courseoffer = Userrole::updateOrCreate([                            
                'user_id' => Auth::id(),
                'role_id' => 2,                                 
            ],[                                
                'role_id' => 2,                        
            ]);
        }
        $check_role_corresponding_author = Userrole::where('user_id',Auth::id())->where('role_id',7)->first(); 
        // 2 means author       
        if(empty($check_role_corresponding_author))
        {
            $courseoffer = Userrole::updateOrCreate([                            
                'user_id' => Auth::id(),
                'role_id' => 7,                                 
            ],[                                
                'role_id' => 7,                        
            ]);
        }

        $check_highest_priority = check_highest_priority($request->majorcategory_id);
        if ($check_highest_priority) 
        {
            $get_eligible_editorial_member = $check_highest_priority->user_id;
        } 
        else 
        {
            $get_eligible_editorial_member = get_eligible_user($request->majorcategory_id,$request->subcategory_id);
            if (is_object($get_eligible_editorial_member)) 
            {
                $get_eligible_editorial_member = $get_eligible_editorial_member->send_to_user_id;
            }
            else
            {
                $get_eligible_editorial_member = $get_eligible_editorial_member;
            }
        }
        
        // Start save into history table        
        $videohistory = new videohistory();
        $videohistory->videoupload_id = $video_details_step5->id;
        $videohistory->videohistorystatus_id = 1; // from videohistorystatuses table
        $videohistory->send_from_user_id = Auth::id();
        $videohistory->send_to_user_id = $get_eligible_editorial_member;
        $videohistory->send_from_as = 'Author';
        $videohistory->send_to_as = 'editorial-member';
        //$videohistory->send_to_as = 'editor-in-chief';
        $videohistory->save();
        // End save into history table
        $request->session()->flash('success', 'Record saved successfully.');
        $request->session()->flash('videoid', $video_details_step5->unique_number);
    }
    DB::commit();
    return response()->json(['success'=>'Successfully','redirect' => route('my.account')]);
    } catch (Exception $e) {
        // Rollback the transaction if any operation fails
        DB::rollBack();

        // Log or handle the exception
        // For example:
        // Log::error($e->getMessage());

        // Return error response
        return response()->json(['error' => $e->getMessage()]);
    }
}

In the code. I have to send step wise messages. Like, if one step completes then user will see one step is completed like that.
For this, I’ve added different-different response after completing each step and then call again the store method.
Everything is good.

But I need transaction’s rollback. Means if there occurs any error into any step then all the record must be rollback.
But currently, the record of current step is rolled back, not the transactions of previous step.
Means, if step1 is successfully completed then it will go on step2. Then if any error occurs in the step2, then only step2 records are being rolled back. And records of step1 is not being rolled back. How can I roll back all the transaction?