标签: optimistic-concurrency

实体框架乐观并发异常未发生

我们有一个ASP.Net MVC应用程序,它使用EF4作为其数据访问层,我们看到当我们认为它们应该是没有抛出OptimisitcConcurrencyExceptions时的意外行为.

我们已将问题简化为以下代码...

   using System.Linq;
    using Project.Model;

    namespace OptimisticConcurrency
    {
        class Program
        {
            static void Main()
            {
                Contact firstContact = null;
                using (var firstEntities = new ProjectEntities())
                {
                    firstContact = (from c in firstEntities.Contacts 
                       where c.LastName == "smith" select c).Single();
                }

                using (var secondEntities = new ProjectEntities())
                {
                    var secondContact = (from c in secondEntities.Contacts 
                       where c.LastName == "smith" select c).Single();

                    secondContact.Title = "a";
                    secondEntities.SaveChanges();
                }

                firstContact.Title = "b";

                using (var thirdEntities = new ProjectEntities())
                {
                    var thirdContact = (from …
Run Code Online (Sandbox Code Playgroud)

optimistic-concurrency entity-framework-4 asp.net-mvc-3

6
推荐指数
1
解决办法
4322
查看次数

System.Web.Providers的OptimisticConcurrencyException

我正在使用Microsoft 的新Universal Develors进行SQL Server会话.SQL Server上的旧会话实现需要一个作业(每分钟运行一次)来清除过期的会话.新的一个检查并清除每个请求.由于我实际上是在SQL Azure中运行,因此我没有SQL Agent来安排作业,所以这听起来像是一种合理的方式(不,我不想为会话支付Azure Cache).

问题是当多个用户同时访问该站点时,他们都试图同时清除相同的过期会话,第二个获得乐观的并发异常.

System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
   at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
   at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Web.Providers.DefaultSessionStateProvider.PurgeExpiredSessions()
   at System.Web.Providers.DefaultSessionStateProvider.PurgeIfNeeded()
   at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Run Code Online (Sandbox Code Playgroud)

我正在使用ELMAH进行错误记录,这显示出一些频率.在我尝试配置ELMAH以忽略错误之前,有没有人知道一种方法来阻止错误发生在第一位?是否有一些我缺少的新提供商的配置?

sql-server asp.net asp.net-mvc optimistic-concurrency

6
推荐指数
1
解决办法
902
查看次数

使用.NET进行MongoDB乐观并发控制

使用.NET MongoDB API(MongoDB.Driver),实现乐观并发控制的推荐方法是什么?例如,有什么类似于SQL Server的ROWVERSION/TIMESTAMP,例如,每当文档更改时自动更新的属性?还是有触发机制?还是其他任何机制?

.net mongodb optimistic-concurrency mongodb-.net-driver

6
推荐指数
1
解决办法
2001
查看次数

Model First方法中的EF Concurrency Handling with Timestamp属性

我试图在ASP.NET MVC应用程序中实现使用Entity Framework处理并发中给出的解决方案.

文章说:

将跟踪属性添加到部门实体

在Models\Department.cs中,添加一个跟踪属性:

[Timestamp] 
public Byte[] Timestamp { get; set; }
Run Code Online (Sandbox Code Playgroud)

Timestamp属性指定此列将包含在发送到数据库的Update和Delete命令的Where子句中.

由于我使用的是模型第一种方法,因此我遵循了使用Entity Framework创建时间戳列中概述的步骤1 - 5

  1. 将名为"Timestamp"的属性添加到EF模型中的实体
  2. 将类型设置为二进制
  3. 将nullable设置为false
  4. 将StoreGeneratedPattern设置为Computed
  5. 将ConcurrencyMode设置为Fixed

当我从数据库模型更新我的代码时,Models\Department.cs现在包含

    public virtual byte[] Timestamp
    {
        get;
        set;
    }
Run Code Online (Sandbox Code Playgroud)

然后我使用元数据类来指定Timestamp属性:

// Metadata for Department entity
public class DepartmentMetadata
{
    [Timestamp]
    public byte Timestamp { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Q1.Timestamp在行编辑的情况下,我测试了列的值是否发生了变化.事实并非如此.

编辑1问题是由于SQL Server列类型binary,它应该是类型的原因引起的timestamp.更改数据类型修复了Timestamp列未更新的问题.

Q2.我试图修改同一个实体(使用"在新标签页中打开")来查看是否OptimisticConcurrencyException抛出了一个实体.事实并非如此.我究竟做错了什么?请帮助我理解,谢谢.

我的<code> Timestamp </ code>属性的屏幕截图

.net optimistic-concurrency entity-framework-4

5
推荐指数
1
解决办法
3762
查看次数

使用Microsoft.WindowsAzure.StorageClient.TableServicesContext并检测并发更新冲突

问题是System.Data.Services.Client.dll和Microsoft.Data.Services.Client.dll中都存在一些类(DataServiceClientException/DataServiceRequestException/DataServiceResponse).简单的方法是只使用其中一个库.不幸:

  • 无法删除System.Data.Services.Client.dll,因为它是使用Microsoft.WindowsAzure.StorageClient.TableServicesContext所必需的
  • Azure上的Microsoft.WindowsAzure.StorageClient.TableServicesContext需要Microsoft.Data.Services.Client.dll.

通常这两个库可以很好地协同工作.但是,从此处实现代码以检测并发冲突会导致错误:

Error   1   The type 'System.Data.Services.Client.DataServiceRequestException' exists in both 'C:\Program Files\Microsoft WCF Data Services\5.0\bin\.NETFramework\Microsoft.Data.Services.Client.dll' and 'C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.Services.Client.dll'
Error   2   The type 'System.Data.Services.Client.DataServiceResponse' exists in both 'C:\Program Files\Microsoft WCF Data Services\5.0\bin\.NETFramework\Microsoft.Data.Services.Client.dll' and 'C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.Services.Client.dll'
Error   3   The type 'System.Data.Services.Client.DataServiceClientException' exists in both 'C:\Program Files\Microsoft WCF Data Services\5.0\bin\.NETFramework\Microsoft.Data.Services.Client.dll' and 'C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.Services.Client.dll'
Run Code Online (Sandbox Code Playgroud)

因为System.Data.Services.Client.DataServiceClientException,DataServiceRequestExceptionDataServiceResponse类都无法访问,因为它们存在于两个库中.在使用Microsoft.WindowsAzure.StorageClient.TableServicesContext时如何检测并发更新冲突?

.net optimistic-concurrency azure-table-storage

5
推荐指数
1
解决办法
541
查看次数

使用对多个客户端的乐观并发检查实现事件存储

我正在尝试使用符合我所看到的各种 Greg Young 启发示例的实践和原则来实现一个事件溯源系统。

我了解版本检查逻辑是如何工作的,并且在保存聚合时,如果当前版本与预期版本不匹配,则意味着另一个会话/客户端应用程序在您之前更新了聚合。

我也知道您可以制定一种在保存并发事件时追溯解决冲突的方法,这个问题与这样做无关。

我想了解的是,在使用 nosql 数据库(例如 ravendb)作为事件存储的特定实现中,我将如何确保写入的事件不会因竞争条件而与版本号重叠。

以下代码来自一个示例项目来说明:

Repository<TAggregate>存储库类中有一个保存方法

    public void Save(AggregateRoot aggregate, int expectedVersion)
    {
        if (aggregate.GetUncommittedChanges().Any())
        {
            lock (_lockStorage)
            {
                var item = new T();

                if (expectedVersion != -1)
                {
//issue if two processes get to this line of code below together 
//and both have the same 'version to be expected' then start writing together
                    item = GetById(aggregate.Id); 
                    if (item.Version != expectedVersion)
                    {
                        throw new ConcurrencyException(string.Format("Aggregate {0} has been previously modified",
                                                                     item.Id));
                    } …
Run Code Online (Sandbox Code Playgroud)

optimistic-concurrency ravendb event-sourcing

5
推荐指数
1
解决办法
680
查看次数

正确处理 DbUpdateConcurrencyException

这是来自关于 DBContext 生命周期的文档:

使用 Windows Presentation Foundation (WPF) 或 Windows 窗体时,请为每个窗体使用一个上下文实例。这使您可以使用上下文提供的更改跟踪功能。

我读过 a 的生命周期DBContext应该尽可能,但显然在WinForms(我正在使用的)的情况下,这条规则不适用,建议使用其他规则。

当前设置

我的应用程序也遵循MVC模式,在我的控制器中,我已经初始化了DBContext. 现在,当表单关闭时,除其他外,控制器实例也会被处理,这就是上下文消失的地方。如果重要的话,我也使用数据库优先方法。

现在,始终打开一个上下文(按表单)似乎有其自身的便利(您可以轻松跟踪上下文的更改),但是例如,我发现自己(作为EF初学者)有一些疑问......看看这个情况:

我有IList在创建表单时初始化的用户(用户实体)。我运行我的应用程序的两个(甚至更多)实例,因为它旨在在多用户环境中工作。现在,假设用户 A 和用户 B 都加载了相同的记录(用户管理屏幕,所以他们都是管理员)......现在事情是这样的:

用户A对某些记录B进行更改(更新)用户对同一记录进行更改(更新)并将其保存到数据库 用户A尝试保存DbUpdateConcurrencyException被抛出...

现在这很好,我知道一个术语乐观并发,并说用户AB正在更新同一行(或同一列),我会处理这样的异常(如果我遗漏了什么,请纠正我):

catch (DbUpdateConcurrencyException ex)
{
    ex.Entries.Single().Reload();
    //Here I reload UI with a new changes, and ask a user to try again         
}
Run Code Online (Sandbox Code Playgroud)

现在这似乎有效......因为只要我的表单还活着,我的上下文就会打开,当我对 ex.Entries.Single() 执行 Reload() 时,列表中的特定用户(请记住我已经提到了之前的用户列表) 用实际的数据库值刷新,因此当我重新加载视图时,用户获得当前状态。

实际问题 …

c# winforms optimistic-concurrency entity-framework-6 visual-studio-2017

5
推荐指数
0
解决办法
1202
查看次数

事件存储和乐观并发

Greg Young 在他关于 CQRS 的文档“构建事件存储”部分中,将事件写入事件存储时,他检查了乐观并发。我真的不明白他为什么要检查,谁能用一个具体的例子向我解释。

optimistic-concurrency cqrs event-sourcing eventstoredb

5
推荐指数
1
解决办法
678
查看次数

Azure 表存储 (412) 先决条件失败

我已将 GitHub 解决方案用于URLshortener并将其部署在我的 Azure 租户上。现在突然我收到一个错误:

"Exception while executing function: Functions.UrlIngest. 
Microsoft.Azure.WebJobs.Host: Error while handling parameter keyTable after 
function returned:. Microsoft.WindowsAzure.Storage: The remote server 
returned an error: (412) Precondition Failed."
Run Code Online (Sandbox Code Playgroud)

在研究这个问题时,我找到了一个链接,上面写着:

"If the entity's ETag differs from that specified with the update request,
the update operation fails with status code 412 (Precondition Failed). This 
error indicates that the entity has been changed on the server since it was 
retrieved. To resolve this error, retrieve the entity again …
Run Code Online (Sandbox Code Playgroud)

azure optimistic-concurrency azure-table-storage azure-functions

5
推荐指数
1
解决办法
5327
查看次数

LINQ 中的更新查询包含 WHERE 子句中的所有列,而不仅仅是主键列

我正在使用 Linq 更新表中的单个列,请使用下面的虚构表格。

MyTable(PKID、ColumnToUpdate、SomeRandomColumn)

var row = (from x in DataContext.MyTable
           where b.PKID == 5
           select x).FirstOrDefault();

row.ColumnToUpdate = 20;
DataContext.SubmitChanges();
Run Code Online (Sandbox Code Playgroud)

这会将专栏更新为预期的内容,这并不奇怪。但是,当我检查生成的 SQL 命令时,它会执行以下操作:

UPDATE [dbo].[MyTable ]
SET [ColumnToUpdate ] = @p2
WHERE ([PKID] = @p0) AND ([SomeRandomColumn] = @p1) 
Run Code Online (Sandbox Code Playgroud)

这是执行更新,但前提是所有列都与实体期望的值匹配,而不是单独引用主键列。

如果数据库列被另一个进程更改,这在这个特定项目中是非常可行的;例如。在获取要操作的行、计算要设置值的更改以及以一批行形式发出更新命令之间存在一个窗口。在这种情况下,查询将引发异常,从而导致部分更新,除非我捕获、重新加载数据并重新发送单个查询。它还有一个缺点,即行信息可能非常大(例如,包含 HTML 标记),并且整个信息都会传递给 SQL,并在处理较大批次时减慢系统速度。

有没有办法让 Linq / Entity 仅根据Where 子句中的 PK 列发出更新命令?

linq linq-to-sql optimistic-concurrency

4
推荐指数
1
解决办法
685
查看次数