如何在C#中使多个数据库操作成为原子/一个事务?

时间:2015-09-14 21:17:39

标签: c# .net atomic transactionscope

我需要使代码低于原子/失败或成功作为一个单元。我怎么能实现这个目标呢?

void Processor(Input input)
{
    var mapper = new Mapper(recordDetails);
    int remainingRecords = GetCountForRemainingRecords(recordDetails);
    try
    {
        while (remainingRecords > 0)
        {
            mapper.CreateRecords(dataset);
            Validate(dataset);
            //the Save(dataset) uses SqlBulkCopy maps tables, transaction, and saves it..
            Save(dataset);
            //I cannot perform the operation below on the dataset directly because dataset doesn't have the records that is in the database
            //the method below eventually calls a stored proc that sends a list of users that was recently created
            OutdateDuplicateUsers(dataset.userTable);
            remainingRecords = MethodToGetUpdatedCount();
        }
    }
    catch (Exception exception)
    {
        //exception handler..
    }
}

现在,如果我的OutdateDuplicateUsers抛出异常,我仍然会得到Save方法持久化的帐户。我不希望这种情况发生。 我希望Save和OutdateDuplicateUsers方法都是原子的。我阅读了关于TransactionScope的this篇文章,看来它正是我想要的。但是,我无法让它发挥作用。从文章中可以直接看到这个实现,但我自己也无法实现它。

我尝试了什么:

void Processor(Input input)
{
    var mapper = new Mapper(recordDetails);
    int remainingRecords = GetCountForRemainingRecords(recordDetails);
    try
    {
        while (remainingRecords > 0)
        {
            using (var scope = new TransactionScope())
            {
                try
                {
                    mapper.CreateRecords(dataset);
                    Validate(dataset);
                    //the method Save(dataset) is using SqlBulkCopy; maps tables, uses transaction, and saves it..
                    Save(dataset);
                    //I cannot perform this opertaion on the dataset directly because dataset doesn't have the records that is in the database
                    //the method below eventually calls a stored proc that sends a list of users that was recently created
                    OutdateDuplicateUsers(dataset.userTable);
                    remainingRecords = MethodToGetUpdatedCount();
                    scope.Complete();
                }
                catch (Exception)
                {
                    //not both at the same time. I tried using both, one at a time though.
                    TransactionScope.Dispose();
                    TransactionScope.Current.Rollback();
                    //exception handler

                }
            }
        }
    }

}

更新: 数据集是强类型数据集,仅为架构。 CreateRecords和Validate方法根据业务逻辑填充数据。 'mapper'接收recordDetails,例如,用户列表(更新了片段)。 我的意思是不起作用是如果OutdateDuplicateUser()方法抛出异常并且无法完成过时操作,我仍然可以看到记录已经从Save(dataset)方法保存在数据库中,我正在尝试防止。

0 个答案:

没有答案