C#怎么把数据完整的插入到sql,你们都是怎么做的?
我一个dataset里有三个表,如何保证数据的完整性?也就是要么全部插入,要么不插入任何数据。
由于我有的用户网络不稳定,经常断网,造成数据不完整,用事务的话,会独占,执行事务的时候,其他操作就不能执行。等待事务结束后,才能操作,这样会使并发操作的用户出现问题的。如下面的图所示,我要把他改成什么形式,可以保证数据的完整性呢?我今天试用事务,但是事务没结束时,断网了,然后再连上网时,涉及到的表好像都被锁住了,都不能进行操作了。用下图这种方式插入数据,也有断网,数据没能完全插入的可能,这种方式插入的速度比上图一条条插入的快。大家都贴一下你们是怎么保证数据的完整性,把数据都插入到服务器的。提供商一下思路。

解决方案 »

  1.   

    使用事务
    具体参考:
    http://msdn.microsoft.com/zh-cn/library/vstudio/86773566.aspx
      

  2.   

    Transaction应该可以吧,不Commit就是rollback.
      

  3.   

    我是这样用的~
    String ConnStr = "Data Source=.\\SQLEXPRESS;Database=DB;User ID=sa;Password=***";  //宣告_ConnStr為字串//C#  SQLtransaction的使用方法
    //步驟1:引用[System.Data.SqlClient],在C#中想對資料庫存取都要用到這個class,所以請記得Using 
    //using System.Data.SqlClient//步驟2: 建立SqlConnection,SqlCommand,SqlTransaction
    //建立資料庫的連線
    //(connstr為連線的字串,可以使用web.config中的connectionstring Tag設定)
    SqlConnection conn = new SqlConnection(ConnStr);//建立第一個cmd物件,用以執行SQL的指令
    //(sqlstr為SQL語法,EX:select getdate(),conn為剛建立的資料庫連線物件)
    SqlCommand cmd = new SqlCommand(@"INSERT INTO TableName( USER_001,USER_002,USER_003) VALUES ('test111','test111','test111') ", conn);//建立第二個cmd物件,用以執行SQL的指令
    //(sqlstr1為另一個SQL語法,EX:select getdate(),conn為剛建立的資料庫連線物件)
    SqlCommand cmd1 = new SqlCommand(@"INSERT INTO TableName( USER_001,USER_002) VALUES ('test111','test111') ", conn);//開始和DB做連線
    conn.Open();//建立交易物件
    SqlTransaction trans1 = conn.BeginTransaction("trans1");//從此行開始使用conn            
    using (conn)
    {
    try
    {
    cmd.Transaction = trans1;    //指定cmd透過trans1做交易
    cmd1.Transaction = trans1;   //指定cmd1透過trans1做交易
    cmd.ExecuteNonQuery();
    cmd1.ExecuteNonQuery();
    trans1.Commit();             //完成交易
    }
    catch (SqlException ex)
    {
    trans1.Rollback();           //取消交易
    MessageBox.Show(ex.ToString());
    }
    finally
    {
    DataTable dt = new DataTable();
    SqlDataAdapter adapter = new SqlDataAdapter(@"Select * from TableName", conn);
    adapter.Fill(dt);
    dataGridView1.DataSource = dt;
    }
    }// 從此行會dispose conn
      

  4.   

    事务时必须的,在这种网络条件下,如果你想更好的确保性能和安全性,就不应该让客户端直接去操作数据库,
    可以写个web服务,DataSet.GetChange()得到需要更新的数据或者传入sql语句的集合到web服务,让它去执行更新
      

  5.   

    当然这个web服务需要和db有良好的通信,最好是同一台服务器上
      

  6.   

    怎么来?能写个例子吗?我是在winform下的。
      

  7.   


    我的理解是你有三张表要一起插入 要么一起回滚数据对么?
    这样的话 你就写一个存储过程
    在存储过程里面先插第一张表 再插入第二张表 再插入第三张表
    这样 要么三个表一起成功 要么都插入不成功
    你要做的就是把三个表的数据一起通过参数传入就行了
    其他的数据库做
    你程序只调用一个存储过程
    参数如果很多的话 建议用xml当参数吧
    里面数据结构各种自己定义
    到了数据库的存储过程在解析下 插入表即可
    不知道讲清楚了么
      

  8.   

    单一数据库 比如sql:SqlTransaction
    多个数据库 比如同时插入到sql oracle:TransactionScope
      

  9.   


    我的理解是你有三张表要一起插入 要么一起回滚数据对么?
    这样的话 你就写一个存储过程
    在存储过程里面先插第一张表 再插入第二张表 再插入第三张表
    这样 要么三个表一起成功 要么都插入不成功
    你要做的就是把三个表的数据一起通过参数传入就行了
    其他的数据库做
    你程序只调用一个存储过程
    参数如果很多的话 建议用xml当参数吧
    里面数据结构各种自己定义
    到了数据库的存储过程在解析下 插入表即可
    不知道讲清楚了么清楚了,参数太多了。
      

  10.   

    用事务来插入数据,事务回滚时,相应的触发器数据会不会回滚啊?因为我这每次插入数据都会触发一个触发器。代码如下 public void shuju()
            {
                using (SqlConnection conn = new SqlConnection(lianjie.sqcon))
                {
                    conn.Open();
                    SqlCommand cmd = new SqlCommand();
                    cmd.Connection = conn;
                    SqlTransaction tx = conn.BeginTransaction();
                    cmd.Transaction = tx;
                    try
                    {
                       
                       int hangs = int.Parse(hangshu);                    //销售出库表单
                        string xsckd2 = "insert into ERP_XSCKD (jbrj,danhj,kdsjj,xsmdj,bmbmj,xsckj,ckbmj,jinej,bdlxj,bdlxbmj,jbrghj) values ('" + denglu.name + "','" + shouyin.danhao + "',CONVERT(varchar(100), GETDATE(), 120),'" + xsmd + "','" + bmbm + "','" + cangkuming + "','" + cangkubianhao + "','0','销售出库单','300116','" + denglu.account + "')";
                        cmd.CommandText = xsckd2;
                        cmd.ExecuteNonQuery();
                        for (int i = 0; i < hangs; i++)
                        {                        //----------------------------------------------------------【销售单、销售支付信息表和销售明细单】-----------------------------------------------------------------------------------                               #region//销售出库表单
                            if (i == 0)
                            {
                                #region//销售支付信息表
                                                            //销售支付信息表
                                for (int j = 0; j < dataGridView1.RowCount; j++)
                                {
                                    string XSZF = "insert into ERP_XSZF (danhj,xsckmxidj,zffsj,zffsbmj,zfjej) values ('" + shouyin.danhao + "','xsckmxid','" + dataGridView1.Rows[j].Cells[0].Value + "','" + dataGridView1.Rows[j].Cells[4].Value + "','" + dataGridView1.Rows[j].Cells[3].Value + "')";
                                    cmd.CommandText = XSZF;
                                    cmd.ExecuteNonQuery();
                                }
                                #endregion                        }
                            #endregion                        #region//销售出库明细表
                            string xsckd3 = "insert into ERP_XSCKMX (danhj,spmcj,sptmj,shulj,xfjej,cpbjj,xfzkj,hykj,kykdjj,hykdedmj,kdsjj,xsmdj,bmbmj,xsckj,ckbmj) values ('" + shouyin.danhao + "','" + ListP[i].Name.Trim() + "','" + ListP[i].Code.Trim() + "','" + ListP[i].Amount.Trim() + "','" + ListP[i].shifu.Trim() + "','" + ListP[i].yuanjia.Trim() + "','" + ListP[i].Discount.Trim() + "','" + huiyuan.hyk + "','" + huiyuan.kykdj + "','" + huiyuan.hykdedm + "',CONVERT(varchar(100), GETDATE(), 120),'" + xsmd + "','" + bmbm + "','" + cangkuming + "','" + cangkubianhao + "')";
                            cmd.CommandText = xsckd3;
                            cmd.ExecuteNonQuery();
                            #endregion
                        }
                                      tx.Commit();
                        done = true;
                       
                    }
                    catch (Exception ex)
                    {
                        tx.Rollback();
                        done = false;
                        throw new Exception(ex.ToString());
                    }
                }
            }