在我的公司,我们使用IBM DB2 for i5 / OS .NET提供程序DLL版本12.0.7.3。在对iSeries进行数据库调用的Web应用程序中。我们遇到这样一种情况:创建连接的方法然后将该连接传递给子例程似乎有时会访问错误的数据。示例如下:假设服务器刚刚启动。客户A调用" GetContractPdf"它成功了。然后,客户端B调用相同的方法并且失败。服务器重新启动,客户端B调用" GetContractPdf"然后成功的方法。客户端A调用它并且失败。
我把头发拉出来试图解决这个问题,但似乎代码并没有正确处理或处理数据库连接。它在我的开发环境中是可重现的,当我重现它时,连接对象显示我曾经调用它的客户端的正确库列表,但是在插入一个测试查询后会生成可以轻松识别被触摸的客户端数据库的数据这绝对是错误的数据。有问题的数据库在具有不同库列表的同一物理AS / 400机器上运行。拥有自己的AS / 400的第三个客户不受此问题的影响。
我一直在更改任何接受连接作为参数的方法来创建自己的连接,并希望它不会造成太大的性能损失。
以下是生成连接的方法:
public static iDB2Connection GetConnection(string ClientCode)
{
string decrypted = "";
try
{
decrypted = System.Configuration.ConfigurationManager.ConnectionStrings[ClientCode].ConnectionString;
}
catch (Exception)
{
throw new FaultException(string.Format("Client connection string not found for {0}.", ClientCode));
}
try
{
decrypted = EncryptDecrypt.Decrypt(decrypted);
}
catch (Exception)
{
throw new FaultException(string.Format("Error determining connection string for client {0}.", ClientCode));
}
try
{
return new iDB2Connection(decrypted);
}
catch (Exception)
{
throw new FaultException("Error accessing database.");
}
}
这里有一些伪代码,显示了问题行为出现时的使用方式:
public static ContractObject GetContract(clientCode,contractId){
using(iDb2Connection conn = GetConnection(clientCode)){
ContractObject contractObject = new ContractObject(){
Id = contractId
};
GetSomeData(contractObject,conn);
GetOtherData(contractObject,conn);
return contractObject;
}
}
public static void GetSomeData(ContractObject contract, iDb2Connection connection){
string commandText = "Select data from table where conditions";
using(iDb2Command cmd = new iDb2Command(commandText,connection)){
using(iDb2DataReader reader = cmd.ExecuteReader()){
if(reader.HasRows){
contract.Foo = reader["ColumnName"].ToString();
}
}
}
}
public static void GetOtherData(ContractObject contract, iDb2Connection connection){
string commandText = "Select data from table where conditions";
using(iDb2Command cmd = new iDb2Command(commandText,connection)){
using(iDb2DataReader reader = cmd.ExecuteReader()){
if(reader.HasRows){
contract.Bar = reader["ColumnName"].ToString();
}
}
}
}
如果我更改了方法,以便为每个查询创建一个新的连接对象,则行为将被消除。
正如我所看到的那样,有两个可能的问题,要么我做了一些可怕的错误(我当然可以做到),或者IBM dll不能很好地处理传递连接对象(你认为它不太可能但是可能发生)。我确定还有其他可能性,我没有经验/代码盲目看。
你们是否有任何关于可能导致这种行为或问题的想法可能导致我们弄清楚导致这种行为的原因?
提前感谢您的时间。