共用方式為


HOW TO:管理物件服務交易 (Entity Framework)

本主題提供的範例將示範如何定義交易,以便協調使用其他外部作業對物件內容中的物件進行變更。如需詳細資訊,請參閱在物件服務中管理交易 (Entity Framework)

本主題的範例是根據 AdventureWorks Sales Model (EDM)。若要執行此範例中的程式碼,您必須已經將 AdventureWorks Sales Model 加入到專案中,並設定您的專案使用 Entity Framework。若要這樣做,請完成 HOW TO:使用 Entity Data Model 精靈 (Entity Framework) 中的程序。您也必須安裝 Microsoft Windows Message Queuing。

範例

此範例會定義 TransactionScopeTransactionScope 可確保對物件內容中之物件所做的變更會以訊息佇列進行協調。當物件服務將變更儲存至資料庫時,它就會使用這個交易。發生 UpdateException 時,最多會重試兩次作業。當作業成功時,系統就會接受物件內容中的變更。如需詳細資訊,請參閱在物件服務中管理交易 (Entity Framework)

這則範例會使用長時間執行的物件內容,而系統會在交易成功或所有重試作業都已經嘗試過之後處置 (Dispose) 此物件內容。

Option Explicit On
Option Strict On

Imports System
Imports System.Linq
Imports System.Data
Imports System.Data.Objects
Imports System.Messaging
Imports System.Transactions
' Prepend with the root namespace for the project.
Imports AdventureWorksModel
Namespace Microsoft.Samples.Edm
    Public Class TranasctionSample
        Public Shared Sub EnlistTransaction()
            Dim retries As Integer = 3
            Dim queueName As String = ".\Fulfilling"

            ' Define variables that we need to add an item.
            Dim quantity As Short = 2
            Dim productId As Integer = 750
            Dim orderId As Integer = 43680

            ' Define a long-running object context.
            Dim context As AdventureWorksEntities _
                = New AdventureWorksEntities()

            Dim success As Boolean = False

            ' Wrap the operation in a retry loop.
            Dim i As Integer
            For i = 0 To retries - 1 Step i + 1
                ' Define a transaction scope for the operations.
                Using transaction As New TransactionScope()
                    Try

                        ' Define a query that returns a order by order ID.
                        Dim order As SalesOrderHeader = _
                            context.SalesOrderHeader.Where( _
                            "it.SalesOrderID = @id", New ObjectParameter( _
                             "id", orderId)).First()

                        ' Load items for the order, if not already loaded.
                        If Not order.SalesOrderDetail.IsLoaded Then
                            order.SalesOrderDetail.Load()
                        End If

                        ' Load the customer, if not already loaded.
                        If Not order.ContactReference.IsLoaded Then
                            order.ContactReference.Load()
                        End If

                        ' Create a new item for an existing order.
                        Dim newItem As SalesOrderDetail = _
                        SalesOrderDetail.CreateSalesOrderDetail( _
                        0, 0, quantity, productId, 1, 0, 0, 0, Guid.NewGuid(), DateAndTime.Today)
                        
                        'Add new item to the order.
                        order.SalesOrderDetail.Add(newItem)

                        ' Save changes pessimistically. This means that changes 
                        ' must be accepted manually once the transaction succeeds.
                        context.SaveChanges(False)

                        ' Create the message queue if it does not already exist.
                        If Not MessageQueue.Exists(queueName) Then
                            MessageQueue.Create(queueName)
                        End If

                        ' Initiate fulfilling order by sending a message.
                        Using q As New MessageQueue(queueName)
                            Dim msg As New System.Messaging.Message( _
                                String.Format("<order customerId='{0}'>" _
                                              + "<orderLine product='{1}' quantity='{2}' />" _
                                              + "</order>", order.Contact.ContactID, _
                                    newItem.ProductID, newItem.OrderQty))
                            q.Send(msg)
                        End Using

                        ' Mark the transaction as complete.
                        transaction.Complete()
                        success = True
                        Exit For
                    Catch ex As Exception
                        ' Handle errors and deadlocks here and retry if needed.
                        ' Allow an UpdateException to pass through and 
                        ' retry, otherwise stop the execution.
                        If Not TypeOf (ex) Is UpdateException Then
                            Console.WriteLine("An error occured. " _
                                + "The operation cannot be retried." _
                                + ex.Message)
                            Exit Sub
                        End If
                        ' If we get to this point, the operation will be retried.
                    End Try
                End Using
            Next
            If success Then
                ' Reset the context since the operation succeeded.
                context.AcceptAllChanges()
            Else
                Console.WriteLine("The operation could not be completed in " _
                        + retries.ToString + " tries.")
            End If
            ' Dispose the object context.
            context.Dispose()
        End Sub
    End Class
End Namespace
using System;
using System.Linq;
using System.Data;
using System.Data.Objects;
using System.Messaging; 
using System.Transactions; 
using AdventureWorksModel;

namespace Microsoft.Samples.Edm
{
    class TransactionSample
    {
        public static void EnlistTransaction()
        {
            int retries = 3;
            string queueName = @".\Fulfilling";

            // Define variables that we need to add an item.
            short quantity = 2;
            int productId = 750;
            int orderId = 43680;

            // Define a long-running object context.
            AdventureWorksEntities context
                = new AdventureWorksEntities();

            bool success = false;

            // Wrap the operation in a retry loop.
            for (int i = 0; i < retries; i++)
            {
                // Define a transaction scope for the operations.
                using (TransactionScope transaction = new TransactionScope())
                {
                    try
                    {
                        // Define a query that returns a order by order ID.
                        SalesOrderHeader order =
                        context.SalesOrderHeader.Where
                        ("it.SalesOrderID = @id", new ObjectParameter(
                         "id", orderId)).First();

                        // Load items for the order, if not already loaded.
                        if (!order.SalesOrderDetail.IsLoaded)
                        {
                            order.SalesOrderDetail.Load();
                        }

                        // Load the customer, if not already loaded.
                        if (!order.ContactReference.IsLoaded)
                        {
                            order.ContactReference.Load();
                        }

                        // Create a new item for an existing order.
                        SalesOrderDetail newItem = SalesOrderDetail.CreateSalesOrderDetail(
                            0, 0, quantity, productId, 1, 0, 0, 0, Guid.NewGuid(), DateTime.Today);

                        // Add new item to the order.
                        order.SalesOrderDetail.Add(newItem);

                        // Save changes pessimistically. This means that changes 
                        // must be accepted manually once the transaction succeeds.
                        context.SaveChanges(false);

                        // Create the message queue if it does not already exist.
                        if (!MessageQueue.Exists(queueName))
                        {
                            MessageQueue.Create(queueName);
                        }

                        // Initiate fulfilling order by sending a message.
                        using (MessageQueue q = new MessageQueue(queueName))
                        {
                            System.Messaging.Message msg =
                                new System.Messaging.Message(String.Format(
                                    "<order customerId='{0}'>" +
                                    "<orderLine product='{1}' quantity='{2}' />" +
                                    "</order>", order.Contact.ContactID,
                                newItem.ProductID, newItem.OrderQty));

                            // Send the message to the queue.
                            q.Send(msg);
                        }

                        // Mark the transaction as complete.
                        transaction.Complete();
                        success = true;
                        break;
                    }
                    catch (Exception ex)
                    {
                        // Handle errors and deadlocks here and retry if needed.
                        // Allow an UpdateException to pass through and 
                        // retry, otherwise stop the execution.
                        if (ex.GetType() != typeof(UpdateException))
                        {
                            Console.WriteLine("An error occured. "
                                + "The operation cannot be retried."
                                + ex.Message);
                            break;
                        }
                        // If we get to this point, the operation will be retried.
                    }
                }
            }
            if (success)
            {
                // Reset the context since the operation succeeded.
                context.AcceptAllChanges();
            }
            else
            {
                Console.WriteLine("The operation could not be completed in "
                    + retries + " tries.");
            }

            // Dispose the object context.
            context.Dispose();
        }
    }
}

另請參閱

其他資源

How to: Manage EntityClient Transactions (Entity Framework)
How to: Explicitly Manage EntityClient Transactions Using EntityTransaction (Entity Framework)
管理連接和交易 (Entity Framework 工作)