使用ASP .net处理SQL服务器事务

时间:2012-02-28 08:42:01

标签: .net sql select transactions

我有一个调用web服务的ASP .net应用程序。 Web服务调用数据访问类来更新数据库。

我的网络服务中有一段代码片段(实际上是伪代码),类似于以下内容:

Public Function SubmitCheque(//params are passed here)
     //Call sql stored procedure(SP1) to generate a reference Number

     //Begin loop. loop count would be number of records that are in a collection
       //Insert records to database using another stored procedure(SP2) using the
       //reference number generated in the previous step
     //End Loop
End Function

SP1对表执行选择查询,获取最后一行的列值,然后将其序列递增1.假设最后一行的值是ABC02282012 * 56 *,那么我的新参考号将是ABC02282012 * 57 *

SP2执行单个insert语句,它插入的行将具有生成的引用号。

这是预计会出现的问题,我不确定正确的方法。

在我的代码中,SP1和SP2按顺序执行,并且在SP1和SP2之间的毫秒时间间隔内,应用程序的另一个实例可能已执行SP1并且可以获得相同的事务编号。因此,有可能同时访问应用程序的多个用户可能最终获得相同的交易号,这是一个大问题。

我想知道这是SQL服务器会关注的事情,还是我需要以不同的方式重新编写存储过程或代码来实现事务。

请帮助并告诉我您的意见。

1 个答案:

答案 0 :(得分:2)

您可以更好地在单个存储过程中实现所有逻辑,并将语句包装在合适的事务中。

未能使用TransactionScope在交易中登记您的单独操作。 e.g:

try
{
    // Create the TransactionScope to execute the commands, guaranteeing
    // that both commands can commit or roll back as a single unit of work.
    using (TransactionScope scope = new TransactionScope())
    {
        using (SqlConnection connection1 = new SqlConnection(connectString1))
        {
            // Opening the connection automatically enlists it in the 
            // TransactionScope as a lightweight transaction.
            connection1.Open();


           // Call sql stored procedure(SP1) to generate a reference Number                 

           SqlCommand command1 = new SqlCommand(commandText1, connection1);
           returnValue = command1.ExecuteScalar();


          //Begin loop. loop count would be number of records that are in a collection 
              //Insert records to database using another stored procedure(SP2) using the 
              //reference number generated in the previous step 
          //End Loop 

        }
        // The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();
    }
}
catch (TransactionAbortedException ex)
{
    writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message);
}