Если вы видите это, значит, я еще не придумал, что написать.
При работе с PostgreSQL иногда возникает необходимость управлять зависшими запросами, которые могут блокировать миграции или другие важные процессы. В данной статье мы рассмотрим, как проверить активные процессы и блокировки, а также как принудительно завершать зависшие транзакции.
Проверка активных процессов и блокировок Первым шагом для диагностики проблем в базе данных является проверка активных процессов и блокировок. Для этого можно использовать следующий SQL-запрос:
SELECT pid, age(clock_timestamp(), query_start) AS duration, usename, query
FROM pg_stat_activity
WHERE state != 'idle'
AND pid != pg_backend_pid();
Этот запрос вернет информацию о текущих активных процессах, включая их идентификатор процесса (PID), продолжительность выполнения запроса, имя пользователя и сам запрос. Таким образом, можно определить, какие запросы выполняются слишком долго или блокируют другие процессы.
Принудительное завершение зависшей транзакции Если вы обнаружили процесс, который блокирует другие операции, его можно завершить принудительно. Для этого используйте следующий SQL-запрос:
SELECT pg_terminate_backend(pid);
Замените pid на идентификатор процесса, который необходимо завершить. Этот запрос завершит выбранный процесс и освободит ресурсы, которые он занимал.
Завершение всех зависших процессов Если необходимо завершить все зависшие процессы, кроме текущей сессии, можно использовать следующий запрос. Он завершит все процессы, которые находятся в состоянии, отличном от idle, и выполняются более 10 минут:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state != 'idle'
AND pid != pg_backend_pid()
AND query_start < NOW() - INTERVAL '10 minutes';
Этот запрос позволяет автоматизировать процесс очистки зависших запросов, что может быть особенно полезно при выполнении длительных операций или миграций.
Заключение Управление зависшими запросами в PostgreSQL — важная задача для обеспечения стабильной и эффективной работы базы данных. С помощью приведенных выше SQL-запросов можно диагностировать и устранять проблемы, связанные с зависшими процессами, что поможет поддерживать высокую производительность и надежность системы.
Если вы видите это, значит, я еще не придумал, что написать.
<?php
use App\Http\Controllers\ProductController;
use Illuminate\Support\Facades\Route;
Route::post('products', [ProductController::class, 'store'])
->name('products.store');
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Domains\Product\Core\Handlers\CreateProductHandler;
use App\Http\Requests\CreateProductRequest;
use Illuminate\Http\JsonResponse;
class ProductController extends Controller
{
public function store(CreateProductRequest $request, CreateProductHandler $handler): JsonResponse
{
$product = $handler->handle($request->getDto());
return response()->json([
'message' => 'Product created successfully',
'data' => $product
], 201);
}
}
<?php
declare(strict_types=1);
namespace App\Http\Requests;
use App\Domains\Product\Core\DTO\CreateProductDTO;
use Illuminate\Foundation\Http\FormRequest;
class CreateProductRequest extends FormRequest
{
public function authorize(): bool
{
return true; // Здесь можно добавить логику авторизации
}
public function rules(): array
{
return [
'product.name' => 'required|string|max:255',
'product.description' => 'required|string',
'product.price' => 'required|integer|min:0',
'tags' => 'array',
'tags.*' => 'integer|exists:tags,id',
'images' => 'array',
'images.*' => 'string',
];
}
public function getDto(): CreateProductDTO
{
return CreateProductDTO::fromArray($this->validated());
}
}
<?php
declare(strict_types=1);
namespace App\Domains\Product\Core\DTO;
use App\Domains\Product\Core\ValueObjects\ProductVO;
use Illuminate\Support\Arr;
final class CreateProductDTO
{
public function __construct(
public ProductVO $product
public array $tags,
public array $images
) {
}
public static function fromArray(array $data): self
{
return new self(
ProductVO::fromArray(Arr::get($data, 'product')),
Arr::get($data, 'tags', []),
Arr::get($data, 'images', [])
);
}
}
<?php
declare(strict_types=1);
namespace App\Domains\Product\Core\ValueObjects;
use Illuminate\Support\Arr;
final class ProductVO
{
public function __construct(
public string $name,
public string $description,
public float $price
) {
}
public static function fromArray(array $data): self
{
return new self(
Arr::get($data, 'name'),
Arr::get($data, 'description'),
null !== Arr::get($data, 'price') ? (float) Arr::get($data, 'price') : 0
);
}
}
<?php
declare(strict_types=1);
namespace App\Domains\Product\Core\Handlers;
use App\Domains\Product\Core\DTO\CreateProductDTO;
use App\Models\Product;
use Illuminate\Support\Facades\DB;
final class CreateProductHandler
{
public function handle(CreateProductDTO $dto): Product
{
return DB::transaction(function () use ($dto) {
// Создание товара
$product = new Product();
$product->name = $dto->product->name;
$product->description = $dto->product->description;
$product->price = $dto->product->price;
$product->save();
// Привязка тегов
$product->tags()->attach($dto->tags);
// Сохранение изображений
foreach ($dto->images as $image) {
$product->images()->create(['path' => $image]);
}
return $product;
});
}
}
Для успешного использования паттерна “Обработчик” с DTO и VO программист должен иметь уровень подготовки Middle (средний).
{message}