执行DB2存储过程的ADO.Net连接使用iSeries连接返回池化的输出参数值

时间:2016-05-02 20:13:45

标签: asp.net-mvc iis ado.net db2 connection-pooling

[编辑 - 此问题已解决。问题与存储过程中未初始化的参数有关。]

为什么我需要关闭连接池以使其正常工作? [编辑 - 连接池在AS400上发布了共享连接内存区域]

在我的MVC Web应用程序中,我调用DB2存储过程(SP)。 此SP具有与此伪代码类似的多个输入和输出参数:

CreatePO(@REQNO[in], @PO[out], @Approver[out], @ErrorMsg[out])

我的应用程序将数据写入此SP在处理过程中使用的表格,因此当所有数据都到位时,我会调用SP并尝试创建PO。

如果PO创建失败,则@ErrorMsg out参数中将显示错误消息。在这些情况下,@ PO和@Approver参数应为空白。

以下是按顺序发生的事情:

1)我尝试创建我的第一个PO但是存在问题...
   CreatePO(100,空白,空白,空白)
  导致......
   CreatePO(100,空白,空白,'无法确定批准者')

2)我成功创建了第二个PO ...
CreatePO(101,空白,空白,空白)
CreatePO(101,' P1234',' JJONES',空白)

3)我尝试为@REQNO 100重新创建PO     CreatePO(100,空白,空白,空白)
    CreatePO(100,' P1234',' JJONES','无法确定审批者')

步骤3具有冲突的参数。应用程序池将返回步骤2中的PO和审批者以及相应的错误消息。

如果我回收了我的IIS应用程序池,那么结果将回到步骤#1中发生的情况。

我能够得到我添加的预期结果" pooling = false"到连接字符串。但为什么输出参数会以这种方式受到连接池的影响?这似乎更像是一种错误,而不是某种理想的缓存方法。

如果我不粘贴我的代码,有人会弯曲变形,所以这就是......

(看看前两行的结尾)

    'Dim cs As String = "DataSource=mydb;UserID=myuser;Password=mypassword;Naming=System;ConnectionTimeout=180; DefaultIsolationLevel=ReadUncommitted;AllowUnsupportedChar=True;CharBitDataAsString=True; TransactionCompletionTimeout=0;pooling=false"
    Dim cs As String = "DataSource=mydb;UserID=myuser;Password=mypassword;Naming=System;ConnectionTimeout=180; DefaultIsolationLevel=ReadUncommitted;AllowUnsupportedChar=True;CharBitDataAsString=True; TransactionCompletionTimeout=0;"
    Using conn As New iDB2Connection(cs) 
        conn.Open()
        Dim cmd As iDB2Command = New iDB2Command()
        cmd.Connection = conn 

        cmd.CommandType = CommandType.StoredProcedure
        cmd.CommandText = "BF6360CL"

        ' Input parameters
        cmd.Parameters.Add(New iDB2Parameter With {.ParameterName = "@REQNO", .DbType = SqlDbType.Char, .Size = 7, .Value = model.RO})

        ' Output parameters
        Dim opo = New iDB2Parameter With {.ParameterName = "@POORDER", .DbType = SqlDbType.Char, .Size = 7, .Direction = ParameterDirection.Output}
        cmd.Parameters.Add(opo)

        Dim oApprover = New iDB2Parameter With {.ParameterName = "@APPROVER", .DbType = SqlDbType.Char, .Size = 10, .Direction = ParameterDirection.Output}
        cmd.Parameters.Add(oApprover)

        Dim oStatus = New iDB2Parameter With {.ParameterName = "@STATUS", .DbType = SqlDbType.Char, .Size = 3, .Direction = ParameterDirection.Output}
        cmd.Parameters.Add(oStatus)

        Dim oErr = New iDB2Parameter With {.ParameterName = "@ERROR", .DbType = SqlDbType.Char, .Size = 1, .Direction = ParameterDirection.Output}
        cmd.Parameters.Add(oErr)

        ' return value
        Dim oRetval = New iDB2Parameter With {.ParameterName = "@RETURN_VALUE", .DbType = SqlDbType.Char, .Size = 10, .Direction = ParameterDirection.ReturnValue}
        cmd.Parameters.Add(oRetval)

        cmd.ExecuteNonQuery()

        model.PO = opo.Value
        model.Approver = oApprover.Value
        model.Status = oStatus.Value
        model.Err = oErr.Value

    End Using
return model

所以最大的问题是: 为什么地球连接池应该负责出参数值??? 这可能是IBM iSeries iDB2Connection实现中的错误吗?

2 个答案:

答案 0 :(得分:1)

IIS应用程序池按名称缓存存储过程输出参数,并在检测到空值时返回缓存值。 ODBC或iSeries连接会发生这种情况。当我回收应用程序池时,这个缓存的值就消失了。我添加到连接字符串“pooling = false;”,这些缓存的值将不再出现。

答案 1 :(得分:0)

我的老板让我尝试使用iSeries Navigator调用存储过程,只是为了查看out参数包含的内容。男孩很惊讶。

事实证明,存储过程(SP)毕竟是错误的。今天早上我和AS400 RPG开发人员坐在一起,看着他们调试SP。问题与未初始化的记忆有关。

这里是SP的定义: BF6360CL(@ REQNO,@ USER,@ ENVIRONMENT,@ PO [out],@ Approver [out],@ Status [out],@ Error [out])

enter image description here

然后我在iSeries Navigator中重置了与AS400的连接,输出参数重置为
4 = S2.RETU
5 = RN_VAR0000
等...

AS400开发人员现在正在进行更改以初始化变量。当他们完成后,我希望能够将我的程序改回来使用连接池。

当我重置IIS应用程序池时,它会重置我与数据库的连接。这似乎释放了AS400上的已分配内存。

如果有人对Connections和AS400输出参数内存有更多细节,请分享。