我有两个方法“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;
}
答案 0 :(得分:1)
两种方法都使用相同的连接对象。
因为一种方法使用锁而另一种方法不使用:坏事。对于此场景,对象不保证,因此您应该期望它以有趣的方式失败。您应该从两个地方使用相同的锁定对象,或者更好:仅使用隔离代码中的连接,而不是共享连接。使用连接池,在某处拥有共享连接对象非常有用。一个更合适的模式通常是在需要时获取连接,然后将其处理掉。如果底层提供者支持池,这将理想地执行,没有任何同步问题,并将允许并行查询等。例如:
using (var conn = SomeUtilityClass.GetOpenConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = sqlquery;
int rowCount = dbCommand.ExecuteNonQuery();
return 1;
}
并且,重要的是,使用Query
方法执行相同的;没有锁,没有全局共享连接。
我也担心缺乏参数,顺便说一句。这表明你正在打开SQL注入错误。