我写了一个SqlHelper的公共类,里面的方法都是static的 
如: 
public abstract class MySqlHelper 

        internal static int Insert(string cmdText, MySqlParameter[] parameters)
        {
            int id = 0;
            using (MySqlConnection con = new MySqlConnection(ConnectionString))
            using (MySqlCommand cmd = new MySqlCommand(cmdText))
            {
                try
                {
                    PrepareCommand(parameters, cmd, con, CommandType.Text, null);
                    cmd.ExecuteNonQuery();
                    cmd.CommandText = "select @@identity";
                    id = Convert.ToInt32(cmd.ExecuteScalar());
                }
                catch (MySqlException ex)
                {
                    throw ex;
                }
            }
            return id;
        }

然后由一个业务相关的 DAL 类来调用SqlHelper里面的方法 
如: 
public class ShopTypeDAL 

    public int AddShopTypeDAL(ShopType shopType) 
    {
        int id = 0;
        StringBuilder cmdText = new StringBuilder();        cmdText.Append("insert into ShopType (type_name) values (").Append(PARM_TYPE_NAME).Append(");");            
        try
        {
            MySqlParameter [] parameters = new MySqlParameter [] {
                  new MySqlParameter(PARM_TYPE_NAME, MySqlDbType.VarChar, 40, "type_name")
            };
            parameters[0].Value = shopType.Name;
            id = MySqlHelper.Insert(cmdText.ToString(), parameters);
        }
        catch (MySqlException ex)
        {
            System.Console.WriteLine(ex.Message);
        }
        
        return id;
    }
} 最后由web层来调用 
如: 
public class ShopTypeWeb 

    public int AddShopType(ShopType shopType) 
    { 
        ShopType shopType = new ShopType(); 
        ……………………         ShopTypeDAL dal = new ShopTyepDAL(); 
       return dal.AddShopTypeDAL(shopType);        
    } 

我现在的问题是,如果在web层有多个用户同时访问做Insert操作,由于数据层是一个abstract类的static方法,不会实例化 
这样会不会使数据产生混乱?
比如:
当客户端A,B都添加一条记录问题1-1:
当 A 执行到 MySqlHelper.Insert(...) 中的 cmd.ExecuteNonQuery() 时
这时 B 会不会中途执行 MySqlHelper.Insert(...) ?问题1-2:
如果会,这时 B执行到了 cmd.ExecuteNonQuery()
 A 继续执行 cmd.CommandText = "select @@identity"; id = Convert.ToInt32(cmd.ExecuteScalar()); 
这时 id 得到的是 A 添加的那条记录的ID吗 ? 这时的 int id 是由哪个A还是B调用?或者是A 和 B 各会创建一个 id 的副本?问题1-3:
当 A 执行到 MySqlHelper.Insert(...) 中的:
id = Convert.ToInt32(cmd.ExecuteScalar()); 
然后 B也执行到了 
id = Convert.ToInt32(cmd.ExecuteScalar()); 
然后 A 继续执行 renturn id;
这时 id 返回的是 A 还是B 中的值?问题2:
MysqlHelper.Insert(...)这个static方法会让A执行完以后再让B调用,还是会同时被调用?

解决方案 »

  1.   

    首先,虽然方法是静态的,但是这个方法是可以同时被多个线程调用的
    而且方法里的变量在多个线程里是互不相干的
    比如你说的,同时A和B调用这个方法,那么这里就会创建2个Connection,各自进行各自的数据库操作
    也就是说创建了2个数据库会话。
    问题1-1: 
    这种可能性是存在的,也就是并发问题问题1-2: 
    这个id是A添加的那条记录,因为@@identity不受并发影响,只受当前会话限制。问题1-3: 
    这时 id 返回的是 A 中的值? 问题2: 
    会同时被调用? 
      

  2.   

    问题1-3: 
    当 A 执行到 MySqlHelper.Insert(...) 中的: 
    id = Convert.ToInt32(cmd.ExecuteScalar()); 
    然后 B也执行到了 
    id = Convert.ToInt32(cmd.ExecuteScalar()); 
    然后 A 继续执行 renturn id; 
    这时 id 返回的是 A 还是B 中的值? 
    问题2: 
    MysqlHelper.Insert(...)这个static方法会让A执行完以后再让B调用,还是会同时被调用? 
    1. 会发生并发 不过可以使用
    SqlTransaction trans = conn.BeginTransaction(IsolationLevel.Serializable);
    类似事务的操作
    2.会 。获取id 自增id 不会收到影响