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

跟風遠走 提交于 2019-12-12 06:01:16

问题


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_Query =  (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()
}

回答1:


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


来源:https://stackoverflow.com/questions/5383485/entity-framework-4-and-transactions-do-uncommitted-changes-affect-select-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!