Questions tagged «locking»

通过临时授予请求锁定的进程的独占访问权限来管理对共享数据或资源的并发访问的机制。

1
如何在MySQL中交换表?
假设我有一个表foo,其中包含不时计算的一些统计信息。其他查询大量使用它。 这就是为什么我要在其中计算更多最新统计信息foo_new并在计算准备就绪时交换它们。 我可以做 ALTER TABLE foo RENAME foo_tmp; ALTER TABLE foo_new RENAME foo; 但是,如果在foo没有表的情况下查询需要在这两行之间有表,该foo怎么办?我想我必须以某种方式锁定它...还是有另一种方法可以锁定它?


5
在PostgreSQL中并发DELETE / INSERT锁定问题
这很简单,但是我对PG(v9.0)的功能感到困惑。我们从一个简单的表开始: CREATE TABLE test (id INT PRIMARY KEY); 和几行: INSERT INTO TEST VALUES (1); INSERT INTO TEST VALUES (2); 使用我最喜欢的JDBC查询工具(ExecuteQuery),我将两个会话窗口连接到该表所在的数据库。它们都是事务性的(即auto-commit = false)。我们称它们为S1和S2。 每个代码都使用相同的代码: 1:DELETE FROM test WHERE id=1; 2:INSERT INTO test VALUES (1); 3:COMMIT; 现在,以慢速运行此命令,一次在Windows中执行一次。 S1-1 runs (1 row deleted) S2-1 runs (but is blocked since S1 has a write …

4
NOLOCK总是不好吗?
我是一个报表开发人员,想要使我的查询尽可能高效。我曾经和一个DBA一起工作,他告诉我-我相信是因为我一直在生产服务器上处理报表-可以NOLOCK在每个查询中使用。 现在,我与一个NOLOCK在任何情况下都被禁止使用的DBA一起工作-即使我的报告(由于在几个表上严重缺乏索引)正在停止复制和系统更新。我认为,在这种情况下,a NOLOCK将是一件好事。 由于我的大多数SQL培训都针对不同的DBA提出了截然不同的意见,因此我想向各种各样的DBA提出这一要求。

3
将列添加到生产表
在SQL Server 2008 R2上的大型生产表中添加列的最佳方法是什么?根据微软在线书籍: ALTER TABLE中指定的更改将立即实施。如果更改需要修改表中的行,则ALTER TABLE将更新行。ALTER TABLE在表上获取一个模式修改锁,以确保在更改期间没有其他连接甚至引用该表的元数据,除非联机索引操作最后需要非常短的SCH-M锁。 (http://msdn.microsoft.com/zh-cn/library/ms190273.aspx) 在具有数百万行的大型表上,这可能需要一段时间。停电是唯一的选择吗?处理这种情况的最佳方法是什么?

3
使用SELECT-UPDATE模式时管理并发
假设您有以下代码(请忽略这很糟糕): BEGIN TRAN; DECLARE @id int SELECT @id = id + 1 FROM TableA; UPDATE TableA SET id = @id; --TableA must have only one row, apparently! COMMIT TRAN; -- @id is returned to the client or used somewhere else 在我看来,这不能正确地管理并发。仅仅因为您有一笔交易并不意味着其他人不会获得与您获得更新语句之前相同的值。 现在,将代码保持原样(我意识到这可以更好地作为单个语句处理,甚至可以使用自动增量/标识列更好地进行处理),有什么确定的方法可以使其正确处理并发并防止允许两个客户端获得相同竞争条件的竞争条件。 id值? 我非常确定,将WITH (UPDLOCK, HOLDLOCK)SELECT 添加到SELECT即可。该SERIALIZABLE事务隔离级别(因为它拒绝任何人阅读你做了什么,直到移植是在将似乎工作,以及UPDATE:这是假见马丁的答案)。真的吗?他们俩会平等地工作吗?是一个比另一个更好的选择吗? 想象一下,做比ID更新更合法的事情-基于需要更新的读取进行一些计算。可能涉及许多表,其中一些将要写入,而有些则不会。最佳做法是什么? 写完这个问题后,我认为锁定提示会更好,因为那样的话,您只锁定了所需的表,但是我很感谢任何人的投入。 PS:不,我不知道最佳答案,并且确实希望得到更好的理解!:)

3
如何取消SQL Server中的应用锁定请求?
该sp_getapplock存储过程有以下返回值: 0:成功同步授予锁。 1:在等待释放其他不兼容的锁之后,已成功授予该锁。 -1:锁定请求超时。 -2:锁定请求被取消。 -3:锁定请求被选为死锁受害者。 -999:表示参数验证或其他调用错误。 我正在编写一个用于sp_getapplock在数据访问层中调用的包装器,我想知道在什么情况下可以返回-2,以便抛出描述性且有用的异常。显而易见,返回值-1和-3意味着什么,我可以轻松创建导致返回这些值的测试条件。我如何设法获得-2的返回值?

6
我可以依靠顺序读取SQL Server身份值吗?
TL; DR:下面的问题归结为:插入行时,在生成新Identity值和锁定聚集索引中的相应行键之间是否存在机会之窗,外部观察者可以看到更新的值 Identity并发交易插入的价值?(在SQL Server中。) 详细版本 我有一个带有Identity名为的列的SQL Server表CheckpointSequence,这是表的聚集索引(也具有许多其他非聚集索引)的键。通过多个并发进程和线程将行插入表中(处于隔离级别READ COMMITTED,并且没有IDENTITY_INSERT)。同时,有些进程会定期从聚簇索引中读取行,并按该CheckpointSequence列排序(也处于隔离级别READ COMMITTED,并且该READ COMMITTED SNAPSHOT选项处于关闭状态)。 我目前依靠这样的事实,即读取过程永远不会“跳过”检查点。我的问题是:我可以依靠这个财产吗?如果没有,我该怎么做才能实现? 示例:当插入具有标识值1、2、3、4和5 的行时,阅读器在看到具有值4的行之前必须看不到具有值5的行。测试表明该查询包含一个ORDER BY CheckpointSequence子句(和一个WHERE CheckpointSequence > -1子句),只要要读取第4行但尚未提交,就可靠地阻塞,即使第5行已经提交。 我认为至少从理论上讲,这里可能存在一种竞争条件,可能会导致这一假设被打破。不幸的是,关于多个并发事务的工作方式的文档Identity并没有太多说明Identity,而只是说“每个新值都是基于当前的种子和增量生成的”。和“特定交易的每个新值都与表上的其他并发交易不同”。(MSDN) 我的推理是,它必须以这种方式工作: 事务开始(显式或隐式)。 生成标识值(X)。 根据身份值在聚集索引上获取相应的行锁(除非发生锁升级,在这种情况下整个表都被锁定)。 该行已插入。 事务已提交(可能要花很多时间),因此将再次删除该锁。 我认为在第2步和第3步之间,有一个很小的窗口, 并发会话可以生成下一个标识值(X + 1)并执行所有其余步骤, 因此,允许阅读者恰好在该时间点阅读值X + 1,而忽略了X的值。 当然,这种可能性似乎很小。但仍然-可能会发生。可以吗 (如果您对上下文感兴趣:这是NEventStore的SQL Persistence Engine的实现。NEventStore实现一个仅附加事件存储,其中每个事件都获得一个新的,升序的检查点序列号。客户端从按检查点排序的事件存储中读取事件为了执行各种计算,一旦处理了带有检查点X的事件,客户就只考虑“较新的”事件,即带有检查点X + 1及更高版本的事件,因此,至关重要的是永远不能跳过事件,因为它们再也不会被考虑了,我目前正在尝试确定Identity基于-checkpoint的实现是否满足此要求。这些是所使用的确切SQL语句:Schema,Writer的query,读者查询。) 如果我是对的,并且可能出现上述情况,那么我只能看到两种处理方式,但都不令人满意: 在看到X之前看到检查点序列值X + 1时,关闭X + 1并稍后再试。但是,由于Identity当然会产生间隙(例如,当事务回滚时),因此X可能永远不会出现。 因此,相同的方法,但是在n毫秒后接受间隔。但是,我应该假定n的值是多少? 还有更好的主意吗?

3
证明在每个查询中不使用(nolock)提示
您是否曾经有过不使用查询提示的理由? 我WITH (NOLOCK)在每一个查询中都看到一个非常繁忙的服务器。关键是,开发人员认为默认情况下应该启用它,因为他们讨厌在代码中看到它数千次。 我试图解释说,这将允许脏读,最终它们将得到错误的数据,但是他们认为性能的折衷是值得的。(他们的数据库是一团糟;难怪他们会遇到性能问题。) 如果您有一个明确的示例,说明如何针对这种滥用NOLOCK提示的情况进行陈述,那将不胜感激。


6
在Sql Server中,有没有一种方法可以检查选定的一组行是否被锁定?
我们正在尝试更新/删除数十亿行表中的大量记录。由于这是一个受欢迎的表格,因此该表格的不同部分都有很多活动。任何较大的更新/删除活动都会被阻止较长时间(因为它正在等待获取所有行或页锁或表锁的锁),从而导致超时或花费多天才能完成任务。 因此,我们正在更改一次删除少量行的方法。但是我们要检查所选的(例如100或1000或2000行)当前是否已被其他进程锁定。 如果不是,则继续删除/更新。 如果它们被锁定,则移至下一组记录。 最后,回到开始并尝试更新/删除遗漏的内容。 这可行吗? 谢谢,ToC


2
在SQL Server中检测锁定的表或行
我正在尝试了解/学习如何跟踪被阻止会话的详细信息。 因此,我创建了以下设置: create table foo (id integer not null primary key, some_data varchar(20)); insert into foo values (1, 'foo'); commit; 现在,我从两个不同的客户端两次连接到数据库。 第一届会议: begin transaction update foo set some_data = 'update' where id = 1; 我明确地不承诺在那里保留锁。 在第二届会议上,我发表了同样的声明,当然还有人由于锁定而等待。现在,我尝试使用不同的查询浮动,以查看会话2正在等待foo表。 sp_who2 显示以下内容(我删除了一些列以仅显示重要信息): SPID | 现状 BlkBy | DBName | 指令| SPID | 要求 ----- …

2
锁定创建表
在另一个应用程序中,我被糟糕的设计所震惊:多个线程EnsureDatabaseSchemaExists()同时执行一个方法,基本上看起来像这样: IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'MyTable') AND type = N'U') BEGIN CREATE TABLE MyTable ( ... ); END 但是,即使在SERIALIZABLE事务中执行,此代码似乎也不是线程安全的(即,并行代码尝试多次创建表)。有没有机会强迫SELECT语句获取一个锁定,从而防止另一个线程执行相同的SELECT语句? 多线程EnsureSchemaExists()方法是否有更好的模式?

2
在SQL Server中,读锁如何工作?
假设我有以下长期运行的查询 UPDATE [Table1] SET [Col1] = 'some value' WHERE [Col2] -- some clause which selects thousands of rows 并假设上面的查询运行时执行了以下查询 SELECT * FROM [Table1] 在第一个查询完成之前,第一个查询是否会阻止第二个查询运行?如果是这样,则第一个查询是否阻止第二个查询在所有行上运行,或者仅在WHERE子句中涉及的行上运行? 编辑: 假设第二个查询是 SELECT [Col1], [Col2] FROM [Table1] WHERE [Col2] -- some clause whose matching elements overlap those from -- the clause in the first query and …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.