在后台写C#事务处理,例如多附件上传,分主从表
在主表新增开始时启动事务处理,到FOR循环新增从表数据
结束,速度,性能超慢,有什么好的解决办法吗?

解决方案 »

  1.   

    后台代码?
    后台代码建议你看能不能将那个for循环拼接成一个sql,然后执行
    尽量减少开关连接数据库的次数,能共用的对象就不要重复创建。后台代码你也不可能也不方便公布出来,具体优化肯定得看你的代码如何才能制定。
      

  2.   

    SqlConnection con = new SqlConnection(ConnectionDb.conStr);//获取数据库连接
            con.Open();//打开连接
            SqlTransaction sqltra = con.BeginTransaction();//开始事务
            SqlCommand cmd = new SqlCommand();//实例化
            cmd.Connection = con;//获取数据连接
            cmd.Transaction = sqltra;//,在执行SQL时,
            try
            {
                string sql = "insert into OA_MEETING(meeting_id,meeting_name,meeting_title,start_time,end_time,announce_time,explain,reg_emp_id,emc_emp_id,par_emp_id,rep_emp_id,participate,MEETING_TYPE,PROJ_ID,WORK_ID)values('" + id + "',N'" + meetname + "',N'" + meettitle + "','" + starttime + "','" + endtime + "',N'" + djtime + "',N'" + meetinfo + "','" + empid + "','" + meetperson + "','" + lname + "','" + writer + "','" + ccname + "','" + hidsort.Value + "','" + proid + "','" + workid + "')";
                cmd.CommandText = sql;
                cmd.ExecuteNonQuery();            //string meetid = id;
                int size = 0;
                HttpFileCollection files = HttpContext.Current.Request.Files;
                //遍歷上傳文件窗體所有Html控件
                foreach (string NameId in Request.Form)
                {
                    //找到控件ID名前四位為"txt_"的文件說明文本框
                    if (NameId.Substring(0, 4) == "ttx_")
                    {
                        //獲取文本說明
                        if (Request.Form[NameId] != "")
                        {
                            string Explain = Request.Form[NameId];//获取txt文本说明                        HttpPostedFile pstfile = files["fil_" + NameId.Substring(4)];
                            string fileName = "";
                            string fileExtension = "";
                            fileName = System.IO.Path.GetFileName(pstfile.FileName);//上传的文件全名
                            fileExtension = System.IO.Path.GetExtension(fileName);//擴展名
                            string NewName = fileName.Remove(fileName.LastIndexOf("."));//去掉后缀名的文件名
                            string sql1 = "select isnull(max(app_id),0) from OA_MEETING_APPENDIX";
                           
                            int idd = Convert.ToInt32(objConnction.getString(sql1)) + 1;
                            ua.Folder_Exists("Meeting");
                            string filepath = "..\\AtthFiles\\Meeting\\Meeting_" + idd.ToString() + fileExtension;
                            string sqlstr1 = "insert into OA_MEETING_APPENDIX(APP_ID,MEETING_ID,EXPLAIN,APP_PATH) values('" + idd + "','" + id + "',N'" + Explain + "',N'" + filepath + "')";
                            cmd.CommandText = sqlstr1;                        int num = cmd.ExecuteNonQuery();
                            if (num > 0)
                            {
                                pstfile.SaveAs(Server.MapPath("..\\AtthFiles\\Meeting\\Meeting_" + idd.ToString() + fileExtension));
                                size = pstfile.ContentLength / 1024;
                                objDocument.InsertDoc(5, idd, Explain, "", "", DateTime.Now.ToString("yyyy-MM-dd"), Convert.ToInt32(HempID.Value), filepath, size, hidwork.Value, hidpro.Value);
                            }
                        }
                    }
                }
                sqltra.Commit();
            }catch(Exception ex)
            {
                sqltra.Rollback();
            }这是加了事务的代码,大家帮研究一下.
    实际代码并没加事务.因为太慢.
      

  3.   

    建議:
          1. 因為是附件,文件大小也不固定,文件類型也不固定,再加文件數量多。
          如果用正常解決方法,可能效率有點不好。那么多個數據在事務中,事務中數據越來越多,負擔越來越重,”DB機制事務“
    在問,怎么到現在還不Commit.從一定程度上說,DB事務也是有一定的范圍的,如果超過這個范圍,甚至導致電腦OS假死機,DB不穩定,最終上傳失敗了,問題沒有更好的解決掉。      2.我的建議是, 多分析一下。可以把上傳的文件總數量控制一下, 讓事務 一次最多包含可以接受的文件數量,再Commit。然后在重復這樣做。你是把所有附件在一個事務中做的原因是: 要么這一批附件都上傳成功,要么都上傳失敗。
    你是怕: 如果半途中因為OS或者Networking或者DB本身問題,造成程序不能執行.這樣就有些上傳成功,有些上傳失敗。方法一.你給上傳成功附件做上標記A,全部成功上傳后標記A要修改為標記B并成功返回到程序,否,程序或DB要有清理標記A數據.
    方法二.和方法一類似,不刪除已上傳成功的附件,已便下次上傳相同的附件,但是這樣就要求下次上傳的時候,把這次登陸的用戶上傳附件不成功的附件,即標記A 從數據庫SELECT出來。
                       
          總結,這樣主要是為了效率高一點。是為了易于維護和分析。 系統穩定性也好點。
      

  4.   

    foreach里一个一个的执行事务肯定慢了
    foreach里根据上传情况sql,然后放到一个事务里一次执行才好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦)
      

  5.   

    怎么没法编辑来foreach里一个一个的执行事务肯定慢了 
    foreach里根据上传情况拼接sql,然后放到一个事务里一次执行,事务失败就需要删除上传过的文件
    这样如果有10个文件7个上传成功,后面3个出现错误,那还可以写这七个先,然后叫用户再传另外3个,个人觉得还比较友好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦)