Laravel模型中调用存储过程无需等待结果,如何实现?
Laravel异步调用存储过程不等待结果的实现方案
因为默认的DB::update是同步阻塞的,要实现不等待存储过程执行就返回指定内容,核心思路是把存储过程的调用改成异步执行,下面给两种可行方法:
方法一:用Laravel队列(推荐,生产环境首选)
- 先生成一个队列任务文件:
php artisan make:job ExecuteStoredProcedure
- 打开生成的
app/Jobs/ExecuteStoredProcedure.php,写入任务逻辑:
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\DB; class ExecuteStoredProcedure implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $params; public function __construct(array $params) { $this->params = $params; } public function handle() { DB::update('exec usp_save_transactions ?,?,?,?', $this->params); } }
- 修改你模型里的原方法,把同步调用改成分发异步任务:
public function createTestTransaction($id, $stockid, $transactiontypeid, $userid) { // 把存储过程调用丢给队列异步执行,主线程直接往下走 \App\Jobs\ExecuteStoredProcedure::dispatch([ $id, $stockid, $transactiontypeid, $userid ]); $text = "rk"; return $text; }
这样任务会被放到队列里,由后台的队列worker去执行,你的方法会立刻返回rk,完全不管存储过程成功还是失败。
方法二:直接用数据库异步执行(适合不想搭队列的场景)
如果不想用队列,也可以利用数据库驱动的异步特性(以SQL Server为例):
public function createTestTransaction($id, $stockid, $transactiontypeid, $userid) { // 新建数据库连接,开启异步模式 $connection = DB::connection()->getPdo(); $connection->setAttribute(\PDO::SQLSRV_ATTR_ASYNC_ENABLE, true); // 设置超时为0,避免主动中断 $connection->setAttribute(\PDO::SQLSRV_ATTR_QUERY_TIMEOUT, 0); // 异步执行存储过程,不等待结果 $stmt = $connection->prepare('exec usp_save_transactions ?,?,?,?'); $stmt->execute([$id, $stockid, $transactiontypeid, $userid]); // 直接释放资源,不用管执行结果 $stmt = null; $connection = null; $text = "rk"; return $text; }
注意:这种方式依赖数据库和驱动的支持,不同数据库(比如MySQL)的配置不一样,而且存储过程执行出错的话不好排查和处理,稳定性不如队列方案。
重点提醒
不管用哪种方法,你的模型方法都会立刻返回rk,存储过程的执行成功或失败完全不影响返回结果。
内容的提问来源于stack exchange,提问作者Raj Kumar
相关产品推荐
相关产品推荐

