C#.NET中事务处理问题 在后台写C#事务处理,例如多附件上传,分主从表在主表新增开始时启动事务处理,到FOR循环新增从表数据结束,速度,性能超慢,有什么好的解决办法吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 后台代码?后台代码建议你看能不能将那个for循环拼接成一个sql,然后执行尽量减少开关连接数据库的次数,能共用的对象就不要重复创建。后台代码你也不可能也不方便公布出来,具体优化肯定得看你的代码如何才能制定。 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(); }这是加了事务的代码,大家帮研究一下.实际代码并没加事务.因为太慢. 建議: 1. 因為是附件,文件大小也不固定,文件類型也不固定,再加文件數量多。 如果用正常解決方法,可能效率有點不好。那么多個數據在事務中,事務中數據越來越多,負擔越來越重,”DB機制事務“在問,怎么到現在還不Commit.從一定程度上說,DB事務也是有一定的范圍的,如果超過這個范圍,甚至導致電腦OS假死機,DB不穩定,最終上傳失敗了,問題沒有更好的解決掉。 2.我的建議是, 多分析一下。可以把上傳的文件總數量控制一下, 讓事務 一次最多包含可以接受的文件數量,再Commit。然后在重復這樣做。你是把所有附件在一個事務中做的原因是: 要么這一批附件都上傳成功,要么都上傳失敗。你是怕: 如果半途中因為OS或者Networking或者DB本身問題,造成程序不能執行.這樣就有些上傳成功,有些上傳失敗。方法一.你給上傳成功附件做上標記A,全部成功上傳后標記A要修改為標記B并成功返回到程序,否,程序或DB要有清理標記A數據.方法二.和方法一類似,不刪除已上傳成功的附件,已便下次上傳相同的附件,但是這樣就要求下次上傳的時候,把這次登陸的用戶上傳附件不成功的附件,即標記A 從數據庫SELECT出來。 總結,這樣主要是為了效率高一點。是為了易于維護和分析。 系統穩定性也好點。 foreach里一个一个的执行事务肯定慢了foreach里根据上传情况sql,然后放到一个事务里一次执行才好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦) 怎么没法编辑来foreach里一个一个的执行事务肯定慢了 foreach里根据上传情况拼接sql,然后放到一个事务里一次执行,事务失败就需要删除上传过的文件这样如果有10个文件7个上传成功,后面3个出现错误,那还可以写这七个先,然后叫用户再传另外3个,个人觉得还比较友好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦) NBear.Common 有打包下载的吗? 怎么样才能使下拉框可编辑 服务器端的 请给位帮下忙 最好能有全代码 为什么这个按钮要点二下才能进行分页! asp.net Repeater控件做复杂界面求助 如何取得一页面的刷新次数? web页面中DataGrid的打印 借宝地一用:D,北京,寻找.net和j2me开发高手加盟 IIS问题 很着急 解决问题者独得400分! asp.net的Form身份验证如何配置? 急!请问这种动态复合控件如何设计实现?100分 dataTable 的排序与分组 asp.net用什么显示表格数据最好
后台代码建议你看能不能将那个for循环拼接成一个sql,然后执行
尽量减少开关连接数据库的次数,能共用的对象就不要重复创建。后台代码你也不可能也不方便公布出来,具体优化肯定得看你的代码如何才能制定。
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();
}这是加了事务的代码,大家帮研究一下.
实际代码并没加事务.因为太慢.
1. 因為是附件,文件大小也不固定,文件類型也不固定,再加文件數量多。
如果用正常解決方法,可能效率有點不好。那么多個數據在事務中,事務中數據越來越多,負擔越來越重,”DB機制事務“
在問,怎么到現在還不Commit.從一定程度上說,DB事務也是有一定的范圍的,如果超過這個范圍,甚至導致電腦OS假死機,DB不穩定,最終上傳失敗了,問題沒有更好的解決掉。 2.我的建議是, 多分析一下。可以把上傳的文件總數量控制一下, 讓事務 一次最多包含可以接受的文件數量,再Commit。然后在重復這樣做。你是把所有附件在一個事務中做的原因是: 要么這一批附件都上傳成功,要么都上傳失敗。
你是怕: 如果半途中因為OS或者Networking或者DB本身問題,造成程序不能執行.這樣就有些上傳成功,有些上傳失敗。方法一.你給上傳成功附件做上標記A,全部成功上傳后標記A要修改為標記B并成功返回到程序,否,程序或DB要有清理標記A數據.
方法二.和方法一類似,不刪除已上傳成功的附件,已便下次上傳相同的附件,但是這樣就要求下次上傳的時候,把這次登陸的用戶上傳附件不成功的附件,即標記A 從數據庫SELECT出來。
總結,這樣主要是為了效率高一點。是為了易于維護和分析。 系統穩定性也好點。
foreach里根据上传情况sql,然后放到一个事务里一次执行才好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦)
foreach里根据上传情况拼接sql,然后放到一个事务里一次执行,事务失败就需要删除上传过的文件
这样如果有10个文件7个上传成功,后面3个出现错误,那还可以写这七个先,然后叫用户再传另外3个,个人觉得还比较友好如果实时性要求不高的话,还可以使用队列,在系统不忙时自己调度执行,出错时要删掉已上传文件,并向上传者发送消息(这肯定加了不少麻烦)