很难找到死锁并且非常不舒服.
如何在代码中找到死锁的错误源?有没有"死锁模式"?
在我的特殊情况下,它处理数据库,但这个问题对每个死锁都是开放的.
我最近问了很多关于的问题TVar,我仍然对活锁感到担忧.
所以我想到了这个结构:
TVar).然而,B保持其当前重试的优先级. 我相信这个系统可以防止死锁,但也可以防止饥饿(不像TVar).我想知道是否有人实施了这样的系统,因为它看起来相当明显,我不想重新发明轮子.
当然,可以容易地扩展这种方法以允许用户指定优先级.
优先级可能是一对(user_supplied_prio, auto_increment),与user_supplied_prio采取优先次序,但相同优先级的任务以FIFO的顺序解决.
评论/解决方案:
实际上,当我想到它时,我所描述的已经存在于Haskell中,只需使用一个IORef包裹所有数据,并且仅使用atomicModifyIORef.这atomicModifyIORef将确保按顺序应用交易.但是,有人可能认为这意味着数据结构是顺序的(即有效地限于一个线程),但由于懒惰,它实际上是并行的.
要解释这一点,请考虑一个昂贵的功能f.我们将Data.Map使用键"foo" 将其应用于数据.
这取代(foo -> x)了(foo -> future(f x)).这个帖子应该继续解决(f x)实际问题,但在此期间我们可以将g应用于"bar".由于将g应用于"bar"不需要"foo"的结果,我们可以同时解决这个问题.
没有死锁,没有饥饿,最终将处理所有交易(大致按照收到的顺序).
所有关于SQL Server死锁的文档都讨论了操作1锁定资源A然后尝试访问资源B并且操作2锁定资源B并尝试访问资源A的情况.
但是,我常常在一些繁忙的应用程序中看到select和更新之间甚至多个选择之间的死锁.我发现死锁跟踪输出的一些细节非常难以理解但我真的只想了解什么可能导致两个单独操作之间的死锁.当然,如果一个选择具有读锁定,则更新应该在获得独占锁之前等待,反之亦然?
这种情况发生在SQL Server 2005上,而不是我认为这会产生影响.
我所知道的,writelock就像是同步的.
Readlock和writelock以某种方式相互影响.
ReadLock似乎不能单独工作.
让我们先忘掉Hibernate吧.假设我有两个表,A和B.两个事务正在更新这两个表中的相同记录,但是txn 1更新B然后更新A,而txn 2更新A然后更新B.这是一个典型的死锁示例.避免这种情况的最常见方法是预先定义获取资源的顺序.例如,我们应该更新表A然后B.
回到Hibernate.当我们在一个会话中更新大量实体时,一旦我刷新会话,不同实体的更改将为DB生成相应的插入/更新/删除语句.Hibernate是否有一些算法来决定实体之间的更新顺序?如果没有,Hibernate用于防止第1段中描述的死锁情况的方式是什么?
如果Hibernate维护订单,我怎么知道或控制订单?我不希望我的数据库中的显式更新与Hibernate冲突,并导致死锁.
我试图模拟SQL Server上的死锁.
_|worker_id|salary|
1|1 |100 |
2|2 |300 |
Run Code Online (Sandbox Code Playgroud)
交易1在5秒内完成.
/* TRANSACTION 1*/
Use dbmcw;
DECLARE @sal1 INT, @sal2 int;
BEGIN TRAN;
SELECT @sal1 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 1;
WAITFOR DELAY '00:00:05.000';
SELECT @sal2 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 2;
COMMIT TRAN;
Run Code Online (Sandbox Code Playgroud)
交易2在3秒内完成.
/* TRANSACTION 2*/
Use dbmcw;
DECLARE @sal1 INT, @sal2 int;
BEGIN TRAN;
SELECT @sal2 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 2;
SELECT @sal1 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK) …Run Code Online (Sandbox Code Playgroud) 我在MS SQL Server 2005之上运行的.NET 2.0 webapp上遇到非常罕见且烦人的SQL死锁.过去,我们一直在以经验的方式处理SQL死锁 - 基本上调整查询直到它工作.
然而,我发现这种方法非常不令人满意:耗时且不可靠.我更倾向于遵循确定性查询模式,这些模式将确保设计不会遇到任何SQL死锁.
例如,在C#多线程编程中,必须按照字典顺序执行一个简单的设计规则(如锁定),以确保不会发生死锁.
是否有任何SQL编码模式可以保证防死锁?
我花了很多时间(谷歌搜索,反映.net二进制文件等)试图解决以下问题:
我在应用程序中看到了死锁(ASP.NET MVC + EF4).我们有几个EF的上下文,它们是在请求开始时创建的,并在最后被处理掉.有时我们会遇到以下情况:ASP.NET为每个请求创建一个线程,然后线程在访问EF上下文时进入"处于join或sleep"状态.
大多数死锁线程都有一个堆栈跟踪如下:
System.dll!System.ComponentModel.TypeDescriptor.Refresh(object component, bool refreshReflectionProvider) + 0x97 bytes
System.Data.dll!System.Data.SqlClient.SqlCommand.DesignTimeVisible.set(bool value) + 0x22 bytes
System.Data.dll!System.Data.SqlClient.SqlCommand.SqlCommand(System.Data.SqlClient.SqlCommand from) + 0xc9 bytes
System.Data.dll!System.Data.SqlClient.SqlCommand.Clone() + 0x27 bytes
System.Data.dll!System.Data.SqlClient.SqlCommand.System.ICloneable.Clone() + 0x9 bytes
System.Data.Entity.dll!System.Data.Common.DbCommandDefinition.CreateCommandDefinition(System.Data.Common.DbCommand prototype) + 0x47 bytes
System.Data.Entity.dll!System.Data.SqlClient.SqlProviderServices.CreateDbCommandDefinition(System.Data.Common.DbProviderManifest providerManifest, System.Data.Common.CommandTrees.DbCommandTree commandTree) + 0x21 bytes
System.Data.Entity.dll!System.Data.EntityClient.EntityCommandDefinition.EntityCommandDefinition(System.Data.Common.DbProviderFactory storeProviderFactory, System.Data.Common.CommandTrees.DbCommandTree commandTree) + 0x2a1 bytes
System.Data.Entity.dll!System.Data.EntityClient.EntityProviderServices.CreateDbCommandDefinition(System.Data.Common.DbProviderManifest providerManifest, System.Data.Common.CommandTrees.DbCommandTree commandTree) + 0x8e bytes
System.Data.Entity.dll!System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(System.Data.Objects.ObjectContext context, System.Data.Common.CommandTrees.DbQueryCommandTree tree, System.Type elementType, System.Data.Objects.MergeOption mergeOption, System.Data.Objects.Span span, System.Collections.ObjectModel.ReadOnlyCollection<System.Collections.Generic.KeyValuePair<System.Data.Objects.ObjectParameter,System.Data.Objects.ELinq.QueryParameterExpression>> compiledQueryParameters) + 0x113 bytes
System.Data.Entity.dll!System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(System.Data.Objects.MergeOption? forMergeOption) + 0x310 bytes
System.Data.Entity.dll!System.Data.Objects.ObjectQuery<CompuTool.Business.Portal.Desktop>.GetResults(System.Data.Objects.MergeOption? forMergeOption) + …Run Code Online (Sandbox Code Playgroud) 我一直在解决这个问题,但现在我真的想了解出了什么问题.我有一个相当简单的应用程序(它是youtrack的turtoise SVN插件,但我可以用一个简单的winforms应用程序重现这个问题).
我有一个异步方法 ResolveIssue
public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList)
{
await Task.Delay(1000);
return true;
}
Run Code Online (Sandbox Code Playgroud)
创建死锁所需要做的就是在Button事件处理程序中调用此异步方法,并调用Task.Wait或者Task.Result像这样
private void buttonOk_Click(object sender, System.EventArgs e)
{
var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList);
if (asyncResolvedIssue.Result) {} // <== deadlock!
}
Run Code Online (Sandbox Code Playgroud)
现在我明白拥有异步方法并主动等待它是相当奇怪的,但为什么会产生死锁?!
我正在努力用简单的词语解释线程中的"死锁",所以请帮忙.什么可能是"死锁"(例如,在Java中)的最佳示例,以及它如何在步骤中发生以及如何防止它?但是没有深入细节.我知道这就像问两个相反的事情,但仍然.如果您有任何以前的并发编程培训经验 - 那将是一流的!
deadlock ×10
concurrency ×3
sql-server ×3
c# ×2
sql ×2
.net ×1
async-await ×1
haskell ×1
hibernate ×1
java ×1
locking ×1
stm ×1