Как заставить все скрипты не запускаться при ошибке ответа API? - PullRequest
0 голосов
/ 09 октября 2018

Я использую laravel и использую команду laravel для синхронизации своей базы данных

Моя команда laravel для вызова api для синхронизации выглядит так:

<?php
namespace App\Console\Commands;
...
class MySynchronize extends Command
{
    ...
    public function handle()
    {
        DB::statement("SET foreign_key_checks=0");
        Vendor::truncate();
        Location::truncate();
        Item::truncate();
        DB::statement("SET foreign_key_checks=1");

        $requestContent = [
            'auth' => ['Administrator', 'www.Secret.com', 'ntlm']
        ];

        //call api vendor
        try {
            $client = new GuzzleHttpClient();
            $apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Vendor", $requestContent);
            $jsonResponse = json_decode($apiRequest->getBody(), true);

            $data = [];
            foreach ($jsonResponse['value'] as $value) {
                $created_at = Carbon::now();
                $last_modified_at = Carbon::parse($value['Last_Date_Modified']);
                $data[] = [
                    'id' => $value['Code'],
                    'name' => $value['Name'],
                    'last_modified_at' => $last_modified_at,
                    'created_at'=> $created_at,
                    'updated_at'=> $created_at
                ];
            }
            DB::table('vendors')->insert($data);
        } catch (RequestException $re) {
              // For handling exception.
        }

        //call api location
        try {
            $client = new GuzzleHttpClient();
            $apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Location", $requestContent);
            $jsonResponse = json_decode($apiRequest->getBody(), true);

            $data = [];
            foreach ($jsonResponse['value'] as $value) {
                $created_at = Carbon::now();
                $data[] = [
                    'id' => $value['Code'],
                    'description' => $value['Name'],
                    'created_at'=> $created_at,
                    'updated_at'=> $created_at
                ];
            }
            DB::table('locations')->insert($data);
        } catch (RequestException $re) {
              // For handling exception.
        }

        //call api item
        try {
            $client = new GuzzleHttpClient();
            $apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Item", $requestContent);
            $jsonResponse = json_decode($apiRequest->getBody(), true);

            $data = [];
            foreach ($jsonResponse['value'] as $value) {
                $last_modified_at = Carbon::parse($value['Last_Date_Modified']);
                $created_at = Carbon::now();
                $data[] = [
                    'id' => $value['Code'],
                    'description' => $value['Description'],
                    'vendor_code' => $value['Vendor_Code']?$value['Vendor_Code']:null,
                    'last_modified_at' => $last_modified_at,
                    'created_at'=> $created_at,
                    'updated_at'=> $created_at
                ];
            }
            \DB::table('items')->insert($data);
        } catch (RequestException $re) {
              // For handling exception.
        }

        // send output
        echo 'synchronize success';
    }
}

Сначала я удаляю все данные в таблице, используяусечение.Если он удален, он вызовет API для процесса вставки в таблицу

. Моя проблема заключается в том, что на сервере API возникает ошибка.Например, сервер умер или другая ошибка.Это делает данные в моей базе данных пустыми, потому что я запустил truncate

Как улучшить сценарий, чтобы при возникновении ошибки в API усечение не выполнялось?

Что такоелучший способ?Вы используете try catch в try catch, чтобы справиться с этим?

1 Ответ

0 голосов
/ 09 октября 2018

Вы должны взглянуть на транзакции БД: https://laravel.com/docs/5.7/database#database-transactions

Если в закрытии транзакции возникает исключение, транзакция будет автоматически откатываться.

Так что-то подобное может сработать:

public function handle()
{
    DB::transaction(function () {
        // your DB statements
        try {
            // external API calls
        } catch (SomeException $e) {
            // If for any reasons you want to catch the exception inside the closure
            // (logging maybe?), make sure to rethrow it.
            // Otherwise, Laravel won't know it needs to rollback the DB changes
            throw $e;
        }
    });
}
...