1

我有两种方法“ExecuteNoQuery”(执行 dbCommand.ExecuteNonQuery())和“Query”执行(dbCommand.ExecuteReader())。这两种方法都使用相同的连接对象。在 ExecuteNoQuery 方法中实现了一个锁(使用连接对象)和 Query 方法实现了无锁。如果有多个线程,不同的线程同时访问这两个方法,那会发生什么?

注意:在 Query 方法中,自定义连接池是使用相同的对象实现的。

public int ExecuteNoQuery(string sqlquery, Hashtable htData) {
try {
 lock(Myservice.dbcon)  
  {
    using (OracleCommand dbCommand = new OracleCommand(sqlquery, Myservice.dbcon)) 
        {

              int rowCount = dbCommand.ExecuteNonQuery();
              return 1;
        }
  }
}


public OracleDataReader Query(string sqlquery, Hashtable htData)
    {
        try
        {
            OracleDataReader dbReader = null;
            Random ran = new Random();
            int randomnumber = ran.Next(1,5);

           Myservice.dbcon = (OracleConnection) Myservice.htdbcon
           ["Connection_" +randomnumber];

            if (Myservice.dbcon.State != System.Data.ConnectionState.Executing 
              || Myservice.dbcon !=  System.Data.ConnectionState.Fetching)
                {
                    using (OracleCommand dbCommand = new OracleCommand(sqlquery,
                     Myservice.dbcon))
                    { 

                        dbReader = dbCommand.ExecuteReader();
                    }
                }
                return dbReader;

        }
4

1 回答 1

1

这两种方法都使用相同的连接对象。

由于一种方法使用锁而另一种方法不使用:坏事。对于这种情况,对象不做任何保证,因此您应该期望它以有趣的方式失败。您应该在两个地方使用相同的锁对象,或者更好:只使用隔离代码中的连接,而不是共享连接。使用连接池,在某处拥有共享连接对象很少有用。更合适的模式通常是在需要时获取连接,然后将其处理掉。如果底层提供程序支持池,这将在理想情况下执行,没有任何同步问题,并允许并行查询等。例如:

using (var conn = SomeUtilityClass.GetOpenConnection())
using (var cmd = conn.CreateCommand()) 
{
    cmd.CommandText = sqlquery;
    int rowCount = dbCommand.ExecuteNonQuery();
    return 1;
}

并且,重要的是,从方法中做同样Query的事情;没有锁,没有全局共享连接。

顺便说一句,我也会担心缺少参数。这表明您正在接受 SQL 注入错误。

于 2013-02-15T11:31:39.330 回答