waska14/laravel-with-db-transactions

全局使用中间件对所有路由进行数据库事务处理,将每个控制器放在数据库事务中

v4.0.0 2023-03-18 06:12 UTC

This package is auto-updated.

Last update: 2024-09-18 09:19:41 UTC


README

你是否厌倦了为每个控制器方法编写数据库事务?

此包通过中间件解决了此问题。

中间件开始数据库事务,并根据响应(以及配置)提交/回滚它。

文档

安装

通过执行以下命令将包添加到你的 composer.json 中。

composer require waska14/laravel-with-db-transactions

对于 5.5 版本之前的 Laravel 或不使用 自动发现,请在 config/app.php 中注册服务提供者。

'providers' => [
    /*
     * Package Service Providers...
     */
    \Waska\LaravelWithDBTransactions\WithDBTransactionsServiceProvider::class,
],

配置

如果您想更改 默认配置,您必须通过在控制台中运行此命令将默认配置文件发布到您的项目。

php artisan vendor:publish --tag=waska-with-db-transactions-config

此命令将复制文件 [/vendor/waska14/laravel-with-db-transactions/config/waska.with_db_transactions.php][/config/waska.with_db_transactions.php]

默认的 waska.with_db_transactions.php 看起来像

return [
    /*
     * Route names that will be processed without transaction by WithDBTransactions middleware
     */
    'ignore_route_names' => [
        // login
    ],

    /*
     * Request methods that will be processed without transaction by WithDBTransactions middleware
     */
    'ignore_request_methods' => [
        'get',
    ],

    /*
     * Maximum attempts for transaction by default.
     * Note: You can ignore route name, than use middleware with_db_transactions:N where N is the number of attempts.
     */
    'maximum_attempts' => 1,

    /*
     * If response's http status code is any of those, the transaction will be committed.
     * Note: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
     */
    'commit_http_statuses' => [
        200, // OK
        201, // Created
        202, // Accepted
        203, // Non-Authoritative Information
        204, // No Content
        205, // Reset Content
        206, // Partial Content
        207, // Multi-Status (WebDAV)
        208, // Already Reported (WebDAV)
        226, // IM Used

        300, // Multiple Choices
        301, // Moved Permanently
        302, // Found (Previously "Moved temporarily")
        303, // See Other (since HTTP/1.1)
        304, // Not Modified (RFC 7232)
        305, // Use Proxy (since HTTP/1.1)
        306, // Switch Proxy
        307, // Temporary Redirect (since HTTP/1.1)
        308, // Permanent Redirect (RFC 7538)
    ],

    /*
     * Middleware default class.
     * Anytime you can extend/override the class and change namespace of middleware_class
     */
    'middleware_class' => \Waska\LaravelWithDBTransactions\Http\Middleware\WithDBTransactions::class,

    /*
     * Default alias for middleware
     */
    'middleware_alias' => 'with_db_transactions',

    /*
     * List of middleware groups, where will be pushed with_db_transactions middleware by default (from ServiceProvider)
     */
    'middleware_groups' => [
//        'api',
//        'web',
    ],

    /*
     * Maximum attempts for middleware_groups
     * Note: if value is null, default maximum_attempts will be used.
     */
    'maximum_attempts_for_groups' => null,

    /*
     * Before and after action events
     */
    'before_begin_transaction_event' => \Waska\LaravelWithDBTransactions\Events\BeforeBeginTransactionEvent::class,
    'after_begin_transaction_event' => \Waska\LaravelWithDBTransactions\Events\AfterBeginTransactionEvent::class,
    'before_commit_event' => \Waska\LaravelWithDBTransactions\Events\BeforeCommitEvent::class,
    'after_commit_event' => \Waska\LaravelWithDBTransactions\Events\AfterCommitEvent::class,
    'before_rollback_event' => \Waska\LaravelWithDBTransactions\Events\BeforeRollbackEvent::class,
    'after_rollback_event' => \Waska\LaravelWithDBTransactions\Events\AfterRollbackEvent::class,
    'before_every_rollback_event' => \Waska\LaravelWithDBTransactions\Events\BeforeEveryRollbackEvent::class,
    'after_every_rollback_event' => \Waska\LaravelWithDBTransactions\Events\AfterEveryRollbackEvent::class,
];

您可以从配置中全局(自动)管理路由中间件

如果您想 手动管理,您可以使用 middleware_alias(或更改它)作为路由中间件。

手动使用

如果您在配置中将 middleware_groups 定义为空数组,则默认情况下不会对任何路由进行数据库事务处理,直到您手动设置特定 路由/路由组 的中间件。

注意,您还可以填充 middleware_groups 并在需要方法处理数据库事务的任何地方 手动 使用中间件。

默认中间件别名是 with_db_transactions,您也可以在配置中更改它。

注意,所有配置(如 ignore_route_namesignore_request_methodsmaximum_attemptscommit_http_statuses 等)在手动使用此包时也将生效。

动作和事件

从版本 2.0.0 开始,您可以定义在提交/回滚前后执行的闭包。

有 6 个静态函数,您可以使用 Waska\LaravelWithDBTransactions\Helpers\WithDBTransactions 类调用这些函数。

WithDBTransactions::beforeCommit(callable $closure); // Before committing database transaction
WithDBTransactions::afterCommit(callable $closure); // After committing database transaction
WithDBTransactions::beforeRollback(callable $closure); // Before last rollback
WithDBTransactions::afterRollback(callable $closure); // After last rollback
WithDBTransactions::beforeEveryRollback(callable $closure); // Before every (except last) rollback
WithDBTransactions::afterEveryRollback(callable $closure); // After every (except last) rollback

用法

WithDBTransactions::beforeCommit(function () {
    \Log::info('First log and then commit!');
});
WithDBTransactions::afterCommit(function () {
    \Log::info('First commit and then log!');
});

请注意,每个函数可以调用任意次数。所有闭包将以相同的顺序执行。例如

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Waska\LaravelWithDBTransactions\Helpers\WithDBTransactions;

class Controller extends BaseController
{
    public function create(Request $request)
    {
        // your stuff
        WithDBTransactions::beforeRollback(function () {
            \Log::info('log1 before rollback!');
        });
        WithDBTransactions::afterRollback(function () {
            \Log::info('log1 after rollback!');
        });
        WithDBTransactions::afterRollback(function () {
            \Log::info('log2 after rollback!');
        });
        // your stuff
        \App\User::create($request->validated());

        // Some error happened, so middleware rollbacks the transaction
        throw new \Exception('Something went wrong');
    }
}

回滚后 storage/logs/laravel.log 的内容如下

[Y-m-d H:i:s] local.INFO: log1 before rollback
[Y-m-d H:i:s] local.INFO: log1 after rollback
[Y-m-d H:i:s] local.INFO: log2 after rollback

从版本 2.0.0 开始,包还派发 事件

您可以在监听器中监听这些事件,并在其中执行任何操作。

事件列表

  • \Waska\LaravelWithDBTransactions\Events\BeforeBeginTransactionEvent 开始事务前
  • \Waska\LaravelWithDBTransactions\Events\AfterBeginTransactionEvent 开始事务后
  • \Waska\LaravelWithDBTransactions\Events\BeforeCommitEvent 提交前
  • \Waska\LaravelWithDBTransactions\Events\AfterCommitEvent 提交后
  • \Waska\LaravelWithDBTransactions\Events\BeforeRollbackEvent 最先回滚前
  • \Waska\LaravelWithDBTransactions\Events\AfterRollbackEvent 最后回滚后
  • \Waska\LaravelWithDBTransactions\Events\BeforeEveryRollbackEvent 每次回滚前
  • \Waska\LaravelWithDBTransactions\Events\AfterEveryRollbackEvent 每次回滚后