c# - 将 TransactionScopeOption.Suppress 与 SQL Server Compact 4 一起使用

标签 c# .net entity-framework sql-server-ce system.transactions

我在使用带有 Entity Framework 和 System.Transactions.TransactionScope 的 Sql Server CE 4 来抑制部分事务时遇到问题。

下面的简化代码来自演示问题的单元测试。

想法是使 innerScope block (没有事务)成功或失败而不影响 outerScope block (“环境”事务)。这是 TransactionScopeOption.Suppress 的既定目的。

但是,代码失败了,因为似乎整个 SomeTable 表都被 outerScope 中的第一个插入锁定了。在代码中指示的位置,抛出此错误:

“SQL Server Compact 等待锁定超时。设备的默认锁定时间为 2000 毫秒,台式机为 5000 毫秒。可以使用 ssce:默认锁定超时属性在连接字符串中增加默认锁定超时。[ session ID = 2,Thread id = 2248,Process id = 13516,Table name = SomeTable,Conflict type = x lock (x blocks),Resource = PAG (idx): 1046 ]"

[TestMethod()]
[DeploymentItem("MyLocalDb.sdf")]
public void MyLocalDb_TransactionSuppressed()
{
    int count = 0;

    // This is the ambient transaction
    using (TransactionScope outerScope = new TransactionScope(TransactionScopeOption.Required))
    {
        using (MyObjectContext outerContext = new MyObjectContext())
        {
            // Do something in the outer scope
            outerContext.Connection.Open();
            outerContext.AddToSomeTable(CreateSomeTableRow());
            outerContext.SaveChanges();
            try
            {
                // Ambient transaction is suppressed for the inner scope of SQLCE operations
                using (TransactionScope innerScope = new TransactionScope(TransactionScopeOption.Suppress))
                {
                    using (MyObjectContext innerContext = new MyObjectContext())
                    {
                        innerContext.Connection.Open();
                        // This insert will work
                        innerContext.AddToSomeTable(CreateSomeTableRow());
                        innerContext.SaveChanges(); // ====> EXCEPTION THROWN HERE
                        // There will be other, possibly failing operations here
                    }
                    innerScope.Complete();
                }
            }
            catch { }
        }
        outerScope.Complete();
    }

    count = GetCountFromSomeTable();
    // The insert in the outer scope should succeed, and the one from the inner scope
    Assert.AreEqual(2, count);
}

因此,根据 http://msdn.microsoft.com/en-us/library/ms172001,似乎“事务范围内的事务在隔离级别设置为可序列化的情况下执行”

但是,使用以下代码片段更改 TransactionScope 的隔离级别没有帮助:

public void MyLocalDb_TransactionSuppressed()
{
    TransactionOptions opts = new TransactionOptions();
    opts.IsolationLevel = IsolationLevel.ReadCommitted;
    int count = 0;

    // This is the ambient transaction
    using (TransactionScope outerScope = new TransactionScope(TransactionScopeOption.Required, opts))
    ...

在相同的位置抛出相同的异常。

似乎避免这种情况的唯一方法是在进入 innerScope block 之前调用 outerScope.Complete()。但这会破坏目的。

我在这里错过了什么? 谢谢。

最佳答案

据我所知,SQL Server Compact 不支持嵌套事务。

关于c# - 将 TransactionScopeOption.Suppress 与 SQL Server Compact 4 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10812966/

相关文章:

c# - 在 EF6 中将匿名类型转换为 IEnumerable<>

c# - Linq中默认值的平均扩展方法

c# - Unity ARKit SetWorldOrigin - 错误的旋转

c# - Distinct() 如何在对象列表中查找唯一元素

c# - ASP.NET 的 Wordpress 等价物

c# - 如何在 F# 中处理多个文件和 C# 库?

c# - String.format 无效

mysql - 如何通过 Entity Framework 从数据库中获取单值

c# - Lazy Operator C# 用于自己的数据访问

c# - 通用扩展方法的编译器错误