C#.net在一个方法中锁定对象而在另一个方法中没有锁定

时间:2013-02-15 11:25:47

标签: c# object static locking

我有两个方法“ExecuteNoQuery”(执行dbCommand.ExecuteNonQuery())和“Query”执行(dbCommand.ExecuteReader())。 这两种方法都使用相同的连接对象。在ExecuteNoQuery方法中,实现了一个锁(使用连接对象),并使用out lock实现了Query方法。在多个thred的情况下,不同的线程同时访问该方法然后会发生什么?

注意:在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;

        }

1 个答案:

答案 0 :(得分:1)

  

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

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

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

并且,重要的是,使用Query方法执行相同的;没有锁,没有全局共享连接。

我也担心缺乏参数,顺便说一句。这表明你正在打开SQL注入错误。