[编辑 - 此问题已解决。问题与存储过程中未初始化的参数有关。]
为什么我需要关闭连接池以使其正常工作? [编辑 - 连接池在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实现中的错误吗?
答案 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])
然后我在iSeries Navigator中重置了与AS400的连接,输出参数重置为
4 = S2.RETU
5 = RN_VAR0000
等...
AS400开发人员现在正在进行更改以初始化变量。当他们完成后,我希望能够将我的程序改回来使用连接池。
当我重置IIS应用程序池时,它会重置我与数据库的连接。这似乎释放了AS400上的已分配内存。
如果有人对Connections和AS400输出参数内存有更多细节,请分享。