1

问题

我有一个 CakePHP 应用程序,我在其中调用了一个存储过程:

$this->FileUpload->query('exec sproc_runjob_ProcessTests', false);

此过程会拾取上传的文件并对其进行处理。有时人们会上传多个文件,它会为每个上传的文件调用一次。

问题是我收到了这个错误:

Database Error
Error: SQLSTATE[42000]:
    [Microsoft][SQL Server Native Client 11.0][SQL Server]
    SQLServerAgent Error: Request to run job ProcessTests
    (from User [redacted]) refused because the job already has
    a pending request from User [redacted].
SQL Query: exec sproc_runjob_ProcessTests

据我所知,这意味着存储过程不能同时运行——我必须为每个进程串行运行存储过程,这对我们花哨的新多核服务器来说是一种耻辱。

我们想到的解决方案

  1. 串行运行存储过程

    基本上这里的想法是调用存储过程一次,如果它已经在运行,则忽略它的失败。在 sproc 调用结束时,它会检查数据库以查看它是否需要再次运行(如果有任何“新”文件)并在需要时再次运行自己。

  2. 不要使用现有的存储过程

    由于时间限制,这将是困难的,但如果有人对我们应该这样做的方式提出很好的建议,我会很高兴听到它。

提前致谢!

搜索结果

  1. 看来这家伙也有同样的问题,打电话前先检查一下工作状态就解决了。也许我可以在调用 sproc 之前从 PHP 中做到这一点?

  2. 这里提到了一个叫做 Service Broker 的东西。这实际上可能是我正在寻找的,但我仍然喜欢任何输入。

提前致谢!

4

1 回答 1

0

从您收到的错误消息中,听起来您的存储过程正在尝试启动在 SQL 代理中注册的 SQL 作业。如果这是真的,那么我会推荐另一种策略。

理想情况下,您应该将文件作为二进制类型(例如图像或 blob)直接传递给存储过程。让数据库的多线程处理并发请求的扩展。否则,如果您尝试串行处理文件,应用程序将无法很好地扩展。

Service Broker 实际上是一个端点,它允许您的应用程序以不同的方式连接到数据库。是的,你可以使用它——它会起作用,但我反对它。

或者,您可以继续将文件存储在文件系统上,并且只将文件的路径存储在数据库中。

祝你好运!

于 2012-07-30T01:19:23.840 回答