开发者

Entity Framework 4 and Transactions: Do uncommitted changes affect select results within a transaction?

If I use transactions with Entity Framework 4 like so, will selects on the modified set reflect the newly saved customer IDs within the transaction, or will this generate the same id for each customer?

using ( System.Data.Common.DbTransaction trans = new DbTransaction() )
{
    foreach( var customer in CustomersToSave )
    {  
        // Calculate lowest ID available
        var id_Q开发者_如何学JAVAuery =  (from c in Customers
                     select c.ID).Distinct();
        var lowest_ID_Available = 
            (from p1 in id_Query
             from p2 in id_Query.Where(a => a == p1 + 1).DefaultIfEmpty()
             where p2 == 0
             select p1).Min();

        ... Create a customer with the lowest_ID_Available
    }

    trans.Commit()
}


This will work only if you call SaveChanges after adding each customer which is pretty bad solution. Also this will not run in transaction because DbTransaction alone doesn't work until created from DbConnection by calling BeginTransaction. Use TransactionScope instead.

Another issue is concurrency. Depending on your transaction isolation level other concurrent transactions will either wait for this one to complete or will be able to use same ids as the current transaction.

This is usually handled by separate table which contains only counters. You will create stored procedure to get next counter for given key (table name). The procedure will use atomic update which will set return value and increment current counter in the same time.

Usage of this procedure depends on your requirements. If you require continuos sequence of generated numbers (without holes from rollbacks) then you must lock the record in this special table only for current transaction. If your requirement is only to get unique number but you don't need to have sequence without holes you can use concurrent access.

Example of stored procedure locking the record (if you don't need locking remove hints in update statement):

CREATE PROCEDURE [dbo].[GetNextSequenceValue]
    @SequenceType VARCHAR(20)
AS
BEGIN
    DECLARE @Result INT

    UPDATE [dbo].[Sequences] WITH (ROWLOCK, UPDLOCK)
    SET @Result = Value = Value + 1
    WHERE SequenceType = @SequenceType

    RETURN @Result
END
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜