c# linq to sql 事务插入数据回滚问题。

        using (TransactionScope tran = new TransactionScope())
        {

            using (LinqDataContext lcd = new LinqDataContext())
            {
                lcd.MD_PurchaseActivateCard.InsertOnSubmit(pac);
                lcd.SubmitChanges();
            }

            MD_PurchaseTest pt = new MD_PurchaseTest();
            pt.code = pac.code;
            //pt.encryptcode = ServiceBLL.Encrypt.EncrypTion22(pac.code);
            pt.companycode = pac.companycode;
            pt.companypurchaseplacecode = pac.companypurchaseplacecode;
            InsertPurchaseTest(pt);//插入化验数据

            MD_PurchaseWeight pw = new MD_PurchaseWeight();
            pw.code = pac.code;
            pw.companycode = pac.companycode;
            pw.companypurchaseplacecode = pac.companypurchaseplacecode;
            InsertPurchaseWeight(pw);

            MD_PurchaseSettlement ps = new MD_PurchaseSettlement();
            ps.code = pac.code;
            ps.companycode = pac.companycode;
            ps.companypurchaseplacecode = pac.companypurchaseplacecode;
            ps.settlementtype =0;//此处是为了做二次结算使用的。系统在开卡的时候默认一个1001是正常结算不能改变。
            InsertPurchaseSettlement(ps);

            MD_PurchasePayment pp = new MD_PurchasePayment();
            pp.code = pac.code;
            pp.companycode = pac.companycode;
            pp.companypurchaseplacecode = pac.companypurchaseplacecode;
            pp.docstate = 10;//默认值在此处指定一下。
            InsertPurchasePayment(pp);


            MD_PurchaseInvoice pi = new MD_PurchaseInvoice();
            pi.code = pac.code;
            pi.companycode = pac.companycode;
            pi.companypurchaseplacecode = pac.companypurchaseplacecode;
            pi.docstate = 15;
            InsertPurchaseInvoice(pi);
            
            tran.Complete();

        }

上边我一次性向多个表插入数据,每个表都有一个insert方法。如果有一个插入失败的我想让他都回滚。但现在上边的方法根本不起做用,即使有一个插入失败了,其他的也一样可以插入进去,麻烦各位高人指点一下。如何才能有效呢。

自己体会一下记得结单
两种情况
第一个
任意一个失败回滚
begin transaction t1_student
update sc
set CNo='012'
where SNo='123' and CNo='3'
update sc
set CNo='1'
where SNo='123' and CNo='456'
if @@ERROR!=0
rollback transaction
else
commit transaction t_student

第一个操作失败,事务回滚,成功则设定为保存点,
第二个操作失败,则事务
回滚,查看事务执行结果

begin transaction t_student
update sc
set CNo='45'
where SNo='333' and CNo='123'
if @@ERROR!=0
rollback transaction
save transaction t_student
update sc
set CNo='9'
where SNo='8' and CNo='7'
if @@ERROR!=0
rollback transaction t_student
else
commit transaction t_student

你对Linq to sql 不太了解啊, LinqDataContext 继承于 DataContext 代表一个数据库上下文,在共用一个上下文的情况下,每次会使用同一个数据库连接进行事务提交,而且 Linq to sql 以及后面你可能还会学到的更高级的ORM框架Entity Framework,都是基于隐式事务的方式进行语句提交的,区别式 Linq to sql 是用 SubmitChanges ,而 EF 用的是 SaveChanges 都是一样的,所以这里只要改成这样就可以了

            using (var lcd = new LinqDataContext())
            {
                try
                {
                    lcd.MD_PurchaseActivateCard.InsertOnSubmit(pac);

                    // 在这里执行其它逻辑
                    lcd.MD_PurchaseTest.InsertOnSubmit(new MD_PurchaseTest
                    {
                        code = pac.code,
                        companycode = pac.companycode,
                        companypurchaseplacecode = pac.companypurchaseplacecode
                    });

                    lcd.MD_PurchaseWeight.InsertOnSubmit(new MD_PurchaseWeight
                    {
                        code = pac.code,
                        companycode = pac.companycode,
                        companypurchaseplacecode = pac.companypurchaseplacecode
                    });


                    // SubmitChanges 会隐士的创建一个事务进行完整提交
                    // 且一定要最后再执行SubmitChanges,这样才能以一个事务进行提交
                    // 提交失败会全部回滚,并抛出异常
                    lcd.SubmitChanges();
                }
                catch (Exception ex)
                {
                    // 处理插入失败异常
                    Console.WriteLine(ex.Message);
                }
            }

关键在于共用数据库上下文(DataContext)

   public class LinqDataContext : DataContext
    {
        public LinqDataContext()
            :base("data source=xxx;")
        {

        }

        public Table<MD_PurchaseActivateCard> MD_PurchaseActivateCard { get; set; }
        public Table<MD_PurchaseTest> MD_PurchaseTest { get; set; }
        public Table<MD_PurchaseWeight> MD_PurchaseWeight { get; set; }
        // ... 其它表
    }

希望对你有用

InsertPurchaseTest这个方法贴出来看下 啊

tran.BeginTransaction(); //事务开始

if (tran.Insert(data) <= 0)//判断执行插入语句影响的行数
{
tran.RollbackTransaction();//事务回滚
return;
}

if (tran.InsertWithInt32Identity(data) <= 0)//判断执行插入语句返回的数据ID
{
tran.RollbackTransaction();//事务回滚
return;
}

tran.CommitTransaction();//事务提交
return;