mpyw/laravel-retry-on-duplicate-key
最新稳定版本:v1.3.3
Composer 安装命令:
composer require mpyw/laravel-retry-on-duplicate-key
包简介
Automatically retry non-atomic upsert operation when unique constraints are violated.
README 文档
README
Caution
ABANDONED: Due to changes in Laravel v10.29.0, the functionalities of this library have been integrated into the Laravel core, making the library unnecessary in most cases. Therefore, maintenance will be discontinued. From now on, retry processing will be automatically performed in Model::createOrFirst(), Model::firstOrCreate(), and Model::updateOrCreate(). The only pattern that still has value is for Model::firstOrNew() + save(), but since equivalent processing can be written by yourself, please do not use this library anymore.
Automatically retry non-atomic upsert operation when unique constraints are violated.
e.g. firstOrCreate() updateOrCreate() firstOrNew() + save()
Original Issue: Duplicate entries on updateOrCreate · Issue #19372 · laravel/framework
Requirements
| Package | Version | Mandatory |
|---|---|---|
| PHP | ^8.0 |
✅ |
| Laravel | ^9.0 || ^10.0 |
✅ |
| mpyw/laravel-unique-violation-detector | ^1.0 |
✅ |
| PHPStan | >=1.1 |
Installing
composer require mpyw/laravel-retry-on-duplicate-key
Basic usage
Important
The default implementation is provided by ConnectionServiceProvider, however, package discovery is not available.
Be careful that you MUST register it in config/app.php by yourself.
<?php return [ /* ... */ 'providers' => [ /* ... */ Mpyw\LaravelRetryOnDuplicateKey\ConnectionServiceProvider::class, /* ... */ ], ];
<?php use Illuminate\Support\Facades\DB; $user = DB::retryOnDuplicateKey(function () { // Email has a unique constraint return User::firstOrCreate(['email' => 'example.com'], ['name' => 'Example']); });
| OTHER | YOU |
|---|---|
| SELECT (No Results) |
|
| ︙ | |
| ︙ | SELECT (No Results) |
| ︙ | ︙ |
| INSERT (OK) |
︙ |
| ︙ | |
| INSERT (Error! Duplicate entry) |
|
| Prepare for the next retry, referring to primary connection | |
| SELECT (1 Result) |
Advanced Usage
You can extend Connection classes with RetriesOnDuplicateKey trait by yourself.
<?php namespace App\Providers; use App\Database\MySqlConnection; use Illuminate\Database\Connection; use Illuminate\Support\ServiceProvider; class DatabaseServiceProvider extends ServiceProvider { public function register(): void { Connection::resolverFor('mysql', function (...$parameters) { return new MySqlConnection(...$parameters); }); } }
<?php namespace App\Database; use Illuminate\Database\Connection as BaseMySqlConnection; use Mpyw\LaravelRetryOnDuplicateKey\RetriesOnDuplicateKey; class MySqlConnection extends BaseMySqlConnection { use RetriesOnDuplicateKey; }
Differences from other native upsert implementations
- [8.x] Add upsert to Eloquent and Base Query Builders by paras-malhotra · Pull Request #34698 · laravel/framework
- staudenmeir/laravel-upsert: Laravel UPSERT and INSERT IGNORE queries
These implementations are focused on atomically performing INSERT-or-UPDATE queries. Hence, there are definitely clear differences in usage.
firstOrCreate()updateOrCreate()save auto-increment numbering spaces efficiently.- In contrast,
upsert()always increments the number even if no INSERT occurs and it leads to yield missing numbers. This can be a serious problem if the query is executed frequently. If you still want to go along withupsert(), you may need to consider using UUID or ULID instead of auto-increment.
- In contrast,
firstOrCreate()has clear advantages if its call completes mostly with only one SELECT and rarely with succeeding one INSERT.- In contrast, you must always execute two queries in all cases with
upsert().
- In contrast, you must always execute two queries in all cases with
- As for
updateOrCreate(), there may be extra considerations depending on RDBMS.- For RDBMS other than MySQL,
updateOrCreate()would be better unless its call definitely changes field values on rows.upsert()may ruin thestickyoptimization when the connection has both Reader (Replica) and Writer (Primary) because they assume that all rows narrowed by WHERE conditions have been affected. - In MySQL,
upsert()has no limitations about that. It regards that only rows are affected whose field values are actually changed.
- For RDBMS other than MySQL,
- Be careful that
upsert()never triggers Eloquent events such ascreatedorupdatedbecause its implementation is on Eloquent Builder, not on Model. - Only
upsert()supports bulk insert. It is beneficial if there are a large number of records and you don't need any Eloquent events.
mpyw/laravel-retry-on-duplicate-key 适用场景与选型建议
mpyw/laravel-retry-on-duplicate-key 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 53.06k 次下载、GitHub Stars 达 13, 最近一次更新时间为 2021 年 11 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「database」 「retry」 「laravel」 「constraint」 「illuminate」 「duplicate」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 mpyw/laravel-retry-on-duplicate-key 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 mpyw/laravel-retry-on-duplicate-key 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 mpyw/laravel-retry-on-duplicate-key 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dibi is Database Abstraction Library for PHP
Emulated timeouts for synchronous operations.
Retry tasks that fail due to transient faults
Store your language lines in the database, yaml or other sources
Polling library for conditionally retry operations based on a result checker.
A package for automatically encrypting and decrypting Eloquent attributes in Laravel 5.5+, based on configuration settings.
统计信息
- 总下载量: 53.06k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 13
- 点击次数: 25
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-11-17