我有一个长时间运行的事务(称为 T1),它对 SQL Server 2008 R2 中的表执行一些删除、更新和插入操作。同时,另一个进程会定期从该表中运行 select 语句。
在默认隔离设置下(我认为是 READ COMMITTED?),T1 会阻止任何 select 语句运行,直到事务提交或回滚。
我希望看到的是,即使在事务正在进行时,select 语句也能对一致的数据起作用。我相信 SNAPSHOT 隔离可以提供帮助,但不确定我是否朝着正确的方向前进。这是该应用程序的最佳隔离级别吗?
其次,我无法控制调用 select 语句的进程,但我可以控制调用 T1 的 .NET 应用程序。select 语句和 T1 都需要更改任何隔离级别,还是仅将 T1 标记为具有不同的隔离级别就足够了?
您能否为中级到高级 SQL 专业人员推荐任何好的资源,以对这些资源进行彻底的研究,如果正确学习,可以更好地导航该领域的所有固有缺陷?
我正在考虑各种资源——教程、博客、手册页、PASS 会话或任何东西。
我的任务是识别生产服务器上发生的任何阻塞。我实现这一目标的计划是使用
EXECUTE sp_configure 'blocked process threshold', 5
Run Code Online (Sandbox Code Playgroud)
结合服务器端跟踪来收集阻塞进程报告。
我知道这项活动会影响性能,我想找到某种方法来量化这将是什么。
我知道如何检查数据库是否处于锁定状态,但我的问题是如何找出导致表 /db 锁定的查询。
如果数据库发生意外情况,是否会创建任何日志文件?
I have a table called tblOrderNumber which has 1 row and 1 column. This table stores what the next order number will be for my ecommerce website. It is ABSOLUTELY VITAL that the same order number is not used more than once. Currently the team are using this stored procedure and it seems to work fine:
My question is does UPDLOCK guarantee this? I would have thought a Read Lock is required on the SELECT too (in the unlikely case …
如果我有一个带有 的存储过程set transaction isolation level read uncommitted,它会影响更新语句吗?
我知道你不应该with (nolock)在更新/删除语句上使用,这几乎是一样的,但不确定 SQL 是否在过程中的更新语句上忽略它,或者如果有更新语句我应该小心不要使用它。
编辑:
对困惑感到抱歉。我不是想弄清楚在操作语句上使用这种类型的锁定会产生什么影响,或者这是否是一个好主意。事实上,我不想在操作语句上使用这种锁定,所以我的问题是将“设置事务...”放在我的存储过程的顶部是否会被更新/删除语句所尊重,或者它将被忽略。我希望它只是被忽略。
我完全了解它对 select 语句的影响(及其优点和缺点)。
PostgreSQL 9.6 的情况:
SELECT id FROM A FOR UPDATE;阻塞UPDATE B SET x=y;直到 A 上的锁被释放。
我认为这是因为引用的值可能会改变。我怎样才能在不删除外键约束的情况下避免第一个语句阻塞第二个语句的执行?
如果我放弃外键约束,我应该期待什么坏事?在出现这个问题的实际数据库中,如果表 B 从 A 删除后还有剩余行,这不会是一个重大问题。我们也从不更新主键。
用代码编辑:
-- Setup
create table a (id int primary key);
create table b (id int primary key references a (id) on update cascade on delete cascade, x varchar);
insert into a values (1), (2);
insert into b values (1, null), (2, null);
-- Left
begin;
select 1 from …Run Code Online (Sandbox Code Playgroud) 我有一个 SQL Server 2014 的生产实例,我需要对其进行一些轻度维护。
本质上,我需要在单个事务中替换两个整个表的内容。我想防止任何人在数据更改正在进行时查询任一表。桌子很小,我希望操作不到几秒钟。
不幸的是,我没有为此安排停机时间的好处。
所以问题是如何一次锁定多个对象 - 甚至整个数据库?
理想情况下,我可以简单地获取数据库级锁,进行更改,然后释放锁,但这在 SQL Server 2014 中似乎是不可能的。
我们有一个 mongodb 4.0.10 集群,由 WiredTiger 支持,在生产中,有一个由一个主节点和两个从节点组成的 3 节点副本集。其中一个从站有另一个共同定位的服务,可以广泛地查询从站。在解决协同定位服务中的一些缓慢问题时,我看到了很多令人惊讶的缓慢查询。这个用了 3.3 秒:
find: "myColl",
filter: { myField: "myValue" },
projection: { name: 1 },
$db: "myDb",
$clusterTime: { clusterTime: Timestamp(1568198047, 3), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } },
lsid: { id: UUID("2ed823aa-e6af-4898-a4c1-c039d28a32ab") },
$readPreference: { mode: "secondary" } }
planSummary: IXSCAN { myField: 1 } keysExamined:0 docsExamined:0 cursorExhausted:1 numYields:0 nreturned:0 reslen:232
locks:{ Global: { acquireCount: { r: 1 } },
Database: { acquireCount: { r: 1 } },
Collection: { …Run Code Online (Sandbox Code Playgroud) 许多 PostgreSQLALTER TABLE命令(例如添加具有默认值的新列)在最新版本的 PostgreSQL 中进行了巧妙的优化,一旦 Postgres 短暂获取了表上的锁,即使在大型表上,它们也能基本上立即执行。
不幸的是,最后的警告很重要。链接博客文章中类似这样的命令
ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)
仍然需要等待表上的独占锁users才能运行,尽管一旦获取锁就会立即执行。更糟糕的是,当它等待该锁时,它会阻止涉及该表的所有写入和读取。
重现此问题的一些简单步骤(在 Postgres 13.3 中测试):
在一个psqlshell 中,创建一个表,然后启动一个事务,从表中进行读取,但不提交:
CREATE TABLE users (id SERIAL, name TEXT);
INSERT INTO users (name) VALUES ('bob'), ('fred');
START TRANSACTION;
SELECT * FROM users WHERE id = 1;
Run Code Online (Sandbox Code Playgroud)
让第一个 shell 打开,然后打开第二个 shell 并尝试更改表:
ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)
请注意,此查询挂起,等待第一个 shell …
locking ×10
sql-server ×6
concurrency ×2
postgresql ×2
alter-table ×1
db2 ×1
deadlock ×1
mongodb ×1
mongodb-4.0 ×1
performance ×1
transaction ×1