我找到了一篇MSDN文章,描述了EF在保存更改时如何处理并发:
默认情况下,[...] Object Services将对象更改保存到数据库,而不检查并发性.对于可能经历高度并发性的属性,我们建议在概念层中使用ConcurrencyMode ="fixed"属性定义实体属性
我有两个问题:
在我的模型中没有属性,我ConcurrencyMode="fixed"可以安全地假设如果OptimisticConcurrencyException在保存更改时抛出了一个,那是因为实体不再存在于数据存储中,即它已被其他用户删除,或者我是遗漏了什么?
我想EF执行一个UPDATE看起来像这样的-statement,正如我所看到的那样,只有OptimisticConcurrencyException当ID = 1的Person不存在时才会抛出:
UPDATE Person SET FirstName = 'John' AND LastName = 'Smith' WHERE ID = 1
Run Code Online (Sandbox Code Playgroud)使用时ConcurrencyMode="fixed",EF在删除实体时是否检查并发性?换句话说,EF是否会执行DELETE看起来像这样的-statement(不仅仅是-clause中的主键WHERE):
DELETE FROM Person WHERE ID = 1 AND LastName = 'Doe'
Run Code Online (Sandbox Code Playgroud)我在更新Entity Framework实体中的外键时遇到问题.我正在使用自我跟踪实体并且具有一些具有某种关系的实体,其中外键也作为属性存在(EF4的新特征之一).密钥(整数)标记为Nullable并且修复了并发模式.
具体来说,我有一个与确认用户有很多到0..1关系的Alarm实体.(用户可以确认多个警报,但只能由零个或一个用户确认警报).
实体定义(简化):
Alarm properties
Id Int32 non-nullable identity entity key
UserId Int32 nullable concurrency mode fixed
Alarm navigation properties
User 0..1 multiplicity
User properties
Id Int32 non-nullable identity entity key
Name String non-nullable
Run Code Online (Sandbox Code Playgroud)
在我的自我跟踪实体中,确认用户ID按预期自动生成为Nullable,但是如果我将用户分配给已经持久的警报并运行ApplyChanges,则自我跟踪上下文扩展会尝试设置原始值(null) EF上下文(在上下文扩展中的SetValue中),但是以静默方式跳过,因为EdmType的ClrEquivalentType是一个不可为空的Int32.
自动生成的扩展码:
private static void SetValue(this OriginalValueRecord record, EdmProperty edmProperty, object value)
{
if (value == null)
{
Type entityClrType = ((PrimitiveType)edmProperty.TypeUsage.EdmType).ClrEquivalentType;
if (entityClrType.IsValueType &&
!(entityClrType.IsGenericType && typeof(Nullable<>) == entityClrType.GetGenericTypeDefinition()))
{
// Skip setting null original values on non-nullable CLR types because the ObjectStateEntry …Run Code Online (Sandbox Code Playgroud) entity-framework nullable optimistic-concurrency self-tracking-entities
我有一个数据库,里面有一些表,还有数据.我需要为所有表实现乐观并发.
我想知道什么是最好的方式.
将在应用程序端创建带谓词的查询.
我关心的是如何存储rowversion(timestamp)值.
首先我考虑使用ora_rowscn作为rowversion值,但后来我意识到我必须重新创建所有表来设置ora_rowscn.也许只是添加某种时间戳列会很好,但是我会被迫为应用程序中的每次更新创建并保存一个新的时间戳值.
有任何想法吗 ?
我在ConcurrentDictionary中寻找一个方法,允许我按键删除一个条目,当且仅当该值等于我指定的值时,类似于TryUpdate,但是对于删除.
执行此操作的唯一方法似乎是此方法:
ICollection<KeyValuePair<K, V>>.Remove(KeyValuePair<K, V> keyValuePair)
Run Code Online (Sandbox Code Playgroud)
它是ICollection接口的显式实现,换句话说,我必须首先将ConcurrentDictionary转换为ICollection,以便我可以调用Remove.
删除完全符合我的要求,并且该投射也没什么大不了的,源代码也显示它调用私有方法TryRemovalInternal与bool matchValue = true,所以它看起来都很漂亮和干净.
然而,令我担心的是,它没有被记录为ConcurrentDictionary的乐观并发Remove方法,因此http://msdn.microsoft.com/en-us/library/dd287153.aspx只是重复ICollection样板,并且该如何从一个ConcurrentDictionary添加和删除的项目并不要么提到的方法.
有谁知道这是否可行,或者是否有其他方法我缺席?
是否可以使用Windows Azure表存储服务进行条件插入?
基本上,我想要做的是将新的行/实体插入到表存储服务的分区中,当且仅当我上次查看时该分区中没有任何更改.
如果您想知道,我会考虑事件采购,但我认为问题比这更普遍.
基本上我想阅读部分或整个分区,并根据数据内容做出决定.为了确保自加载数据后分区中没有任何更改,插入应该像普通的乐观并发一样:只有在分区中没有任何更改的情况下插入才会成功 - 没有添加,更新或删除任何行.
通常在REST服务中,我希望使用ETag来控制并发性,但据我所知,分区没有ETag.
我能想到的最好的解决方案是为表中的每个分区维护一个单行/实体,其中包含一个时间戳/ ETag,然后使所有插入包含一个由插入组成的批处理以及这个'的条件更新'时间戳实体'.然而,这听起来有点麻烦和脆弱.
Azure表存储服务可以实现吗?
etag azure optimistic-concurrency event-sourcing azure-table-storage
我知道,当覆盖hashcode()和equals()我的持久化实体的我不应该包括ID,只包括有意义的属性唯一标识对象.但是Hibernate version用于乐观并发控制的字段呢?我应该跳过它,就像ID一样吗?如果让我们说new User(name='John', version=1).equals(new User(name='John',version=2)),不管怎么说它不会混淆Hibernate OCC呢?
hibernate version hashcode optimistic-locking optimistic-concurrency
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
blog.Name = "The New ADO.NET Blog";
bool saveFailed;
do
{
saveFailed = false;
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
saveFailed = true;
// Update the values of the entity that failed to save from the store
ex.Entries.Single().Reload();
}
} while (saveFailed);
}
Run Code Online (Sandbox Code Playgroud)
为什么该方法SaveChanges()被调用Reload()?此调用永远不会更改数据库中的数据.
我正在尝试按顺序实现乐观锁定以避免丢失更新情况.在我的应用程序中,两个用户获取相同的记录,第一个用户通过一些更改更新它.查看相同记录的第二个用户看不到此更改,他自己进行了一些更改并对其进行了更新.由此导致第一批人员失去了.为了防止这种情况,我写了以下内容,但问题仍然存在.我是这个概念的新手,无法识别问题.
我试图通过阅读doc 11.3.4 来实现这一目标.自定义自动版本控制部分.
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>server.bo.Dept</value>
<value>server.bo.Emp</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
<bean id="deptDAO" class="server.dao.DeptDAOImpl">
<property …Run Code Online (Sandbox Code Playgroud)使用.NET MongoDB API(MongoDB.Driver),实现乐观并发控制的推荐方法是什么?例如,有什么类似于SQL Server的ROWVERSION/TIMESTAMP,例如,每当文档更改时自动更新的属性?还是有触发机制?还是其他任何机制?
我有一个中间层,它在共享数据库上执行CRUD操作.当我将产品转换为.NET Core时,我认为我也会考虑使用REST作为API,因为CRUD应该是它的功能.似乎REST对于单个记录操作来说是一个很好的解决方案,但是当我想要删除1000条记录时会发生什么?
每个专业的多用户应用程序都会有一些乐观并发检查的概念:如果没有一些反馈,你就不能让一个用户消除另一个用户的工作.据我了解,REST使用HTTP ETag头记录处理此问题.如果客户端发送的ETag与服务器的标记不匹配,则发出412 Precondition Failed.到现在为止还挺好.但是,当我想删除1,000条记录时,我会使用什么?1,000次单独调用的来回时间是相当可观的,那么REST如何处理涉及Optimistic Concurrency的批处理操作?