MSSQL并发多次运行存储过程

时间:2012-07-25 20:54:10

标签: php sql-server stored-procedures

问题

我有一个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

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

我们想到的解决方案

  1. 连续运行sproc

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

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

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

  3. 提前致谢!

    搜索结果

    1. 看起来this guy有同样的问题,并通过在调用之前检查作业状态来解决它。也许在我打电话之前我可以用PHP做到这一点?

    2. Here's a mention名为Service Broker的东西。这可能实际上是我正在寻找的,但我仍然喜欢任何输入。

    3. 提前致谢!

1 个答案:

答案 0 :(得分:0)

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

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

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

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

祝你好运!