[quote=引用 42 楼 wjfwd2010 的回复:] [quote=引用 38 楼 a295281315 的回复:] 只有提交事务硬盘IO才动作,所以使用事务处理数据并发时能提高性能,如果不使用事务硬盘IO就要动作一次,当多并发的时候,就会造成性能瓶颈。 为了这个事,我们公司请了专家来解决这个事情,现在我们公司所有的软件都已经采用事务的方式批量上传数据,的确效果明显,以前上传几千数据要几分钟(因为有很多软件一起上传),现在只要30多秒。
[quote=引用 38 楼 a295281315 的回复:] 只有提交事务硬盘IO才动作,所以使用事务处理数据并发时能提高性能,如果不使用事务硬盘IO就要动作一次,当多并发的时候,就会造成性能瓶颈。 为了这个事,我们公司请了专家来解决这个事情,现在我们公司所有的软件都已经采用事务的方式批量上传数据,的确效果明显,以前上传几千数据要几分钟(因为有很多软件一起上传),现在只要30多秒。
只有提交事务硬盘IO才动作,所以使用事务处理数据并发时能提高性能,如果不使用事务硬盘IO就要动作一次,当多并发的时候,就会造成性能瓶颈。 为了这个事,我们公司请了专家来解决这个事情,现在我们公司所有的软件都已经采用事务的方式批量上传数据,的确效果明显,以前上传几千数据要几分钟(因为有很多软件一起上传),现在只要30多秒。
使用事务同时提交多个数据表示例 private void Frm_Main_Load(object sender, EventArgs e) { //创建数据库连接对象 SqlConnection sqlConn = new SqlConnection("Data Source=WIN-GI7E47AND9R\\LS;Database=db_TomeTwo;uid=sa;pwd =;"); List<String> strSqls = new List<string>();//创建集合对象 String strDelete1 = "delete From tb_Author Where AuthorId = '99'";//定义删除第一个表的SQL语句 strSqls.Add(strDelete1);//将SQL语句添加到集合中 String strDelete2 = "delete From tb_AuthorsBook Where AuthorId = '99'";//定义删除第二个表的SQL语句 strSqls.Add(strDelete2);//将SQL语句添加到集合中 string strInsert1 = "insert into tb_Author values('99','zhd')";//定义添加第一个表的SQL语句 strSqls.Add(strInsert1);//将SQL语句添加到集合中 string strInsert2 = "insert into tb_AuthorsBook values('66','C#范例大全','99')";//定义添加第二个表的SQL语句 strSqls.Add(strInsert2);//将SQL语句添加到集合中 if (ExecDataBySqls(strSqls, sqlConn))//如果执行成功 { MessageBox.Show("提交tb_Author数据表成功!", "信息提示"); MessageBox.Show("提交tb_AuthorsBook数据表成功!","信息提示"); } else { MessageBox.Show("提交tb_Author数据表失败!", "信息提示"); MessageBox.Show("提交tb_AuthorsBook数据表失败!", "信息提示"); } SqlDataAdapter sqlda1 = new SqlDataAdapter("select * from tb_Author", sqlConn);//创建数据桥接器对象 SqlDataAdapter sqlda2 = new SqlDataAdapter("select * from tb_AuthorsBook", sqlConn);//创建数据桥接器对象 DataSet myds = new DataSet();//创建数据集对象 sqlda1.Fill(myds, "tb_Author");//填充数据集 sqlda2.Fill(myds, "tb_AuthorsBook");//填充数据集 dataGridView1.DataSource = myds.Tables["tb_Author"];//对第一个DataGridView进行数据绑定 dataGridView2.DataSource = myds.Tables["tb_AuthorsBook"];//对第二个DataGridView进行数据绑定 }//codego.net/ /// <param name="strSqls">使用List泛型封装多条SQL语句</param> /// <param name="sqlConn">数据库连接</param> public bool ExecDataBySqls(List<string> strSqls, SqlConnection sqlConn) { bool booIsSucceed = false;//声明提交数据是否成功的标记 SqlCommand sqlCmd = new SqlCommand();//创建SqlCommand对象 sqlCmd.Connection = sqlConn;//设置SqlCommand对象的Connection属性 if (sqlConn.State == ConnectionState.Closed) { sqlConn.Open();//打开数据库连接 } SqlTransaction sqlTran = sqlConn.BeginTransaction();//开始一个事务 try { sqlCmd.Transaction = sqlTran;//设置SqlCommand对象的Transaction属性 foreach (string item in strSqls) { sqlCmd.CommandType = CommandType.Text;//设置命令类型为SQL文本命令 sqlCmd.CommandText = item;//设置要对数据源执行的SQL语句 sqlCmd.ExecuteNonQuery();//执行SQL语句并返回受影响的行数 } sqlTran.Commit();//提交事务,持久化数据 booIsSucceed = true;//表示提交数据库成功 } catch { sqlTran.Rollback();//回滚事务,恢复数据 booIsSucceed = false;//表示提交数据库失败! } finally { sqlConn.Close();//关闭连接 strSqls.Clear();//清除列表strSqls中的元素 } return booIsSucceed;//方法返回值 } 二、在存储过程中使用事务示例 --判断proc_TransInProc存储过程是否存在,如果存在将它删除 if exists(select name from sysobjects where name='proc_TransInProc'and type='p') drop proc proc_TransInProc --删除存储过程 GO create procedure proc_TransInProc as declare @truc int select @truc=@@trancount if @truc=0 begin tran p1 else save tran pl if (@truc=2) begin rollback tran pl return 25 end if(@truc=0) commit tran pl return 0
这个主要是对大型的程序 来说吧。小型的程序根本就不存在并发,也就更没有数据并发这么一回事。 设想:一个操作(比如销售某件东西) 你要更新几十个表 (比如日报表,周报,旬报,月报,季报,年报等), //:为什么要更新这么多,当记录很多的时候,你使用Sum之类的去合计,是不现实的。 这个时候使用存储过程是唯一的选择。 如果你使用.net sqlCmd.Transaction 这个来一条一条更新。那将是要命的。 也许你会向上面的所说。 可能有的人以为用了存储过程就能让一个持续3秒钟的查询变成了30毫秒的查询 可能不会有这么100倍这么大的差距。但有时候一倍的差距也足可以让你需要50台服务完成的事,不用去买100台服务器。
[quote=引用 楼主 wjfwd2010 的回复:] 完全看不明白,题目就是数据并发如何解决。
sql不是自带锁 还需要自己写代码?
110,536
社区成员
642,578
社区内容
加载中
让您成为最强悍的C#开发者
试试用AI创作助手写篇文章吧