- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
已阅读所有其他死锁问题,但似乎这些问题通常是特定于查询的,因此无法通过发布的答案解决我的特定问题。
我有一个针对此数据库运行多个并发更新的 Python 脚本,当线程数设置得太高时,我遇到了死锁。
下面的查询发生了死锁,我不确定应该使用哪种“表提示”组合,或者是否有更好的方法来执行此 UPDATE
语句。
这是我的查询(为简洁起见修改了名称):
BEGIN TRAN
IF EXISTS (SELECT BlahID FROM MyTable WITH (NOLOCK) WHERE BlahID = ?)
BEGIN
UPDATE MyTable SET
Foo = ?,
Bar = 1
WHERE BlahID = ?
END
ELSE
BEGIN
INSERT INTO MyTable (Foo, Bar)
VALUES (1, ?,)
END
COMMIT TRAN
最佳答案
您不需要IF
来检查记录是否已经存在。 UPDATE 语句中的 WHERE
子句可以做到这一点。您只需要确保在插入 新记录之前不存在记录,例如:
UPDATE MyTable
SET
Foo = @foo,
Bar = 1
WHERE BlahID = @id;
INSERT MyTable (Bar,Foo)
values (1,@foo)
where not exists (select BlahID
from MyTable
where BlahID=@id)
如果可能,请使用命名参数,这样您只需传递 2 个参数而不是 4 个,这样就有混淆顺序的风险。
您可以将这两个语句包装在一个事务中,但确保 BlahID 已编入索引。这将允许服务器只锁定一行以进行更新。如果没有索引,服务器将不得不扫描并锁定更多数据以确保一致性。
这也避免了插入重复条目。无论您使用多少锁,如果您使用 IF
子句,使用相同的不存在 ID 的两次并发尝试将导致两次插入,因为两个查询都会找到行丢失,两者都会尝试无条件插入。
另一种选择是使用 MERGE,尽管在这种情况下效果不佳。来自MERGE documentation
When simply updating one table based on the rows of another table, improved performance and scalability can be achieved with basic INSERT, UPDATE, and DELETE statements. For example:
INSERT tbl_A (col, col2)
SELECT col, col2
FROM tbl_B
WHERE NOT EXISTS (SELECT col FROM tbl_A A2 WHERE A2.col = tbl_B.col);
目前的案例更简单,只涉及一张表:
INSERT MyTable (Bar,Foo)
VALUES (1,@foo)
WHERE NOT EXISTS (SELECT BlahID FROM MyTable WHERE BlahID=@id);
为什么会出现僵局?
服务器必须锁定行以确保事务可重复。选择时,服务器对检索或扫描的行采用共享 (S) 锁。这就是为什么有一个索引会导致 更少 锁 - 服务器可以立即找到它需要的行。这些共享锁将在事务期间保持不变。如果没有显式事务,根据隔离模式,共享锁可能会在连接期间保留。这就是 REPEATABLE READ 发生的情况。
当您尝试更新一行时,服务器将尝试获取 UPDATE 锁。如果某行有共享锁,则服务器更新操作将被阻止。如果一个事务已经在一行上持有一个 SHARED 锁,它将尝试将它升级为一个 UPGRADE 锁。如果其他人对该行有 S 锁,则事务将被阻止。要使读取可重复,服务器必须锁定它接触的行。
如果服务器因为缺少索引而无法找到一行,情况会更糟。
NOLOCK 并不意味着没有锁,它意味着不尊重其他人的锁。该操作仍会锁定,但会导致脏结果、重影或丢失更新。
这就是在这种情况下引起 dealock 的原因:
IF(SELECT)
并在行 S1 和 S2 上获得共享锁。您可以在 Locking in the Database Engine 中找到有关锁定、锁定类型、兼容性和范围的更多信息节SQL Server Transaction Locking and Row Versioning Guide
快照隔离
您可以使用 snapshot isolation level避免读者和作者互相阻塞,类似于 Oracle 和 PostgreSQL 所做的。这在这种 情况下无济于事,因为您有一个作者阻止了另一个作者。
关于python - SQL Server 2016 查询引起的死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53088112/
我正在尝试从par_iter()内部捕捉到 panic ,并继续执行par_iter块之后的操作。 如果我有这个,我会正确地获得一切,并且不会出现 panic : let dog: Dog = Dog
我可以假设从 JDK 类加载机制抛出的每个 NoClassDefFoundError 总是在堆栈跟踪中将 ClassNotFoundException 作为原因吗? 另外,NoClassDefFoun
我有下面的程序 package com; import java.io.PrintStream; import java.net.URL; import java.net.UR
我有一些由另一组人编写的简单代码(目前不可用),它引用了我得到的一些 jar 文件。当我编译代码时,一切都构建得很好,但是一旦代码尝试创建在其中一个 jar 文件中定义的类的实例,我就会收到 java
我正在尝试按照 https://github.com/airbrake/airbrake-django#manually-sending-errors-to-airbrake 上的示例进行操作手动向
我不确定为什么这是递归的。 jTable1.getModel().addTableModelListener(new TableModelListener() { public void table
我按照 https://github.com/cloudfoundry/vcap 上的自述文件进行操作 它应该工作正常... 但我得到了这样的错误: 有谁知道发生了什么? 我在 Ubuntu10.04
我只是想知道当你有 UI-Router 的空白页面时,有人知道如何调试情况。 (当然,控制台没有任何错误) 通过为路由器事件执行 console.log(取自 here),我发现它进入了正确的状态,但
我们的网站上有一个问题,一些 Firefox 用户在访问我们的网站时会收到“错误请求”消息(仅此而已,只是“错误请求”字样!) 这似乎是由于 google 跟踪 cookie 损坏,可能是 __utm
在使用guard-rspec在Rails 4项目中运行guard时,在vim中打开/关闭文件时偶尔会看到以下错误。我试过升级/降级guard,guard-rspec,pry和其他没有运气的库。 rub
今天我在编写程序时遇到了这个错误。 Caused by:java.lang.ClassCastException: org.cubeville.blocks.CrossedBlockBrush can
我在执行应用程序时遇到空指针异常,但我不确定原因。问题发生在线路上: task.execute(""); 但我不确定为什么会出现空指针异常。 (我已经验证我有互联网连接,并且它所连接的 XML
嗨,我有一个 java 应用程序,我正在尝试使用它写入 tempDir,但我仍然遇到以下异常。我承认我对编写文件不太了解,所以希望我缺少一些小东西。 Caused by: java.io.FileNo
我不明白为什么会发生这种情况。我对其他问题做了一些研究,发现使用 for 循环时无法修改集合。但是,我正在使用迭代器,为什么它不起作用? int counter = 0; int otherC
目前我正在使用 OSX Server (Yosemite) 来托管一堆 PHP 应用程序,其中一些应用程序在网站文档根目录下有一个子目录用于子域。自更新到 Yosemite 版本的 OSX Serve
SqlCommand objsql = new SqlCommand(); . . objsql.Parameters.AddWithValue("@Param1", DBNull.Value); .
当我尝试将“对象”添加到数据库然后将其显示到 TableView 时,它显示 UnsupportedOperationException 。一切都很好,直到我将此代码添加到“public void i
我收到以下错误日志: 05-29 20:57:29.886: D/AndroidRuntime(359): Shutting down VM 05-29 20:57:29.896: W/dalvikv
我有两个项目,第一个是Ejb3项目,名称是SessionBean,另一个是java项目,名称是SessionBeanClient。对于 IDE,我使用 eclipse indigo。我已经完成了代码,
我有一个使用表单成员身份验证的 ASP.NET Web 应用程序。我们最近进行了渗透测试,标记的一个问题是窃取用户帐户的能力。如果 .ASPXAUTH cookie 值是在注销之前从用户复制的,用户可
我是一名优秀的程序员,十分优秀!