标签: locking

MySQL:事务会锁定行吗?

我之前没有尝试过使用 MySQL 事务,我只是想澄清一些事情。

如果两个用户在非常准确的时间执行查询,MySQL 将如何处理?例如,用户正在尝试更新记录。

user1:更新表集 column = column - 4 where column_id = 1;

user2:更新表集 column = column - 7 where column_id = 1;

现在,如果我使用事务,MySQL 是否会选择首先执行哪个查询并锁定第二个用户,直到提交第一个查询?那是表锁还是行锁?

如果第三个用户将发出 select 语句怎么办?MySQL 将返回的值是什么?

PS 这将在 Innodb 上。

mysql innodb transaction locking

16
推荐指数
1
解决办法
2万
查看次数

如何找到仍然持有锁的查询?

查询sys.dm_tran_locksDMV 会向我们显示哪些会话 (SPID) 持有表、页和行等资源的锁。

对于获取的每个锁,是否有任何方法可以确定导致该锁的 SQL 语句(删除、插入、更新或选择)?

我知道,most_recent_query_handle在列sys.dm_exec_connectionsDMV给了我们执行的最后一个查询的文本,而是多次其他查询同一个会话(SPID)在跑前和仍持有锁。

我已经使用了这个sp_whoisactive过程(来自 Adam Machanic),它只显示了此时输入缓冲区上的查询(想想DBCC INPUTBUFFER @spid),这并不总是(在我的情况下通常永远不会)是获取锁的查询。

例如:

  1. 打开交易/会话
  2. exec 语句(持有资源锁)
  3. 在同一个会话中执行另一个语句
  4. 打开另一个事务/会话并尝试修改在步骤 2 中锁定的资源。

sp_whoisactive过程将指出第 3 步中的语句,该语句不是锁的负责人,因此没有用。

这个问题来自使用Blocked Process Reports功能进行分析,以找出生产中阻塞场景的根本原因。每个事务运行多个查询,并且大多数时候最后一个(显示在 BPR 的输入缓冲区中)很少是持有锁的那个。

我有一个后续问题:有效识别阻塞查询的框架

sql-server locking blocking

16
推荐指数
2
解决办法
1万
查看次数

InnoDB 行锁定 - 如何实现

我一直在环顾四周,阅读 mysql 站点,但仍然无法确切了解它是如何工作的。

我想选择并行锁定写入结果,写入更改并释放锁定。audocommit 已开启。

方案

id (int)
name (varchar50)
status (enum 'pending', 'working', 'complete')
created (datetime)
updated (datetime) 
Run Code Online (Sandbox Code Playgroud)

选择状态为待处理的项目,并将其更新为工作状态。使用独占写入来确保同一项目不会被捡起两次。

所以;

"SELECT id FROM `items` WHERE `status`='pending' LIMIT 1 FOR WRITE"
Run Code Online (Sandbox Code Playgroud)

从结果中获取 id

"UPDATE `items` SET `status`='working', `updated`=NOW() WHERE `id`=<selected id>
Run Code Online (Sandbox Code Playgroud)

我是否需要做任何事情来释放锁,它是否像我上面所做的那样工作?

mysql innodb locking

15
推荐指数
1
解决办法
6万
查看次数

一个简单的选择查询是否获取锁?

我对 SQL Server 很陌生,想了解以下非常简单的select语句是否需要任何锁。

Select * from Student;
Run Code Online (Sandbox Code Playgroud)

请考虑语句不会在begin tran块内运行的情况。

sql-server-2008 sql-server locking

15
推荐指数
2
解决办法
5万
查看次数

锁定 Postgres 以进行 UPDATE / INSERT 组合

我有两张桌子。一个是日志表;另一个本质上包含只能使用一次的优惠券代码。

用户需要能够兑换优惠券,这将在日志表中插入一行并将优惠券标记为已使用(通过将used列更新为true)。

当然,这里存在明显的竞争条件/安全问题。

我过去在 mySQL 的世界里做过类似的事情。在那个世界中,我会全局锁定两个表,在知道这一次只能发生一次的情况下执行逻辑安全,然后在我完成后解锁表。

Postgres 有没有更好的方法来做到这一点?特别是,我担心锁是全局的,但不是必须的——我真的只需要确保没有其他人试图输入那个特定的代码,所以也许一些行级锁会起作用?

postgresql concurrency locking update

15
推荐指数
1
解决办法
2万
查看次数

大量插入阻止选择

我遇到了大量阻止我的 SELECT 操作的 INSERT 的问题。

架构

我有一张这样的表:

CREATE TABLE [InverterData](
    [InverterID] [bigint] NOT NULL,
    [TimeStamp] [datetime] NOT NULL,    
    [ValueA] [decimal](18, 2) NULL,
    [ValueB] [decimal](18, 2) NULL
    CONSTRAINT [PrimaryKey_e149e28f-5754-4229-be01-65fafeebce16] PRIMARY KEY CLUSTERED 
    (
        [TimeStamp] DESC,
        [InverterID] ASC
    ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF
    , IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON)
)
Run Code Online (Sandbox Code Playgroud)

我还有这个小助手程序,它允许我使用 MERGE 命令插入或更新(冲突时更新):

CREATE PROCEDURE [InsertOrUpdateInverterData]
    @InverterID bigint, @TimeStamp datetime
    , @ValueA decimal(18,2), @ValueB decimal(18,2)
AS
BEGIN
    MERGE [InverterData] AS TARGET
        USING (VALUES (@InverterID, …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server locking

15
推荐指数
1
解决办法
3720
查看次数

如何让 SQL 插入和/或更新不锁定 MS SQL Server 上的整个表

DB 工作的新手,所以感谢您对基本问题的耐心。我在本地机器上运行 SQL Server 2014,我有一个小表和一个基本的客户端应用程序来测试不同的方法。我在INSERT INTOandUPDATE语句中都得到了一个表锁。客户端是具有以下代码的 ASP.NET 应用程序:

OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn; …
Run Code Online (Sandbox Code Playgroud)

sql-server locking

15
推荐指数
2
解决办法
6万
查看次数

如何防止 SQLite 数据库锁定?

从 SQLite FAQ 我知道:

多个进程可以同时打开同一个数据库。多个进程可以SELECT同时进行。但是,任何时候只有一个进程可以对数据库进行更改。

所以,据我所知,我可以:1) 从多个线程 ( SELECT) 读取数据库 2) 从多个线程 ( SELECT)读取数据库并从单线程 ( CREATE, INSERT, DELETE)写入

但是,我读到了Write-Ahead Logging,它提供了更多的并发性,因为reader do not block writers and a writer do not block readings。读和写可以同时进行。

最后,当我找到时,我完全糊涂,当指定时:

以下是出现 SQLITE_LOCKED 错误的其他原因:

  • 试图CREATEDROP表或索引而SELECT声明仍悬而未决。
  • 当 aSELECT在同一张表上处于活动状态时尝试写入表。
  • 尝试SELECT在多线程应用程序中同时在同一张表上执行两个操作,如果 sqlite 未设置为这样做。
  • fcntl(3,F_SETLK 对 DB 文件的调用失败。例如,这可能是由 NFS 锁定问题引起的。此问题的一种解决方案是将 DB 移走,然后将其复制回来,使其具有新的 Inode 值

所以,我想为自己澄清一下,有必要避免锁吗?我可以从两个不同的线程同时读取和写入吗?谢谢。

sqlite locking

14
推荐指数
1
解决办法
6万
查看次数

更改 nvarchar 列的大小时,是否需要删除唯一索引?重新创建索引时表会被锁定吗?

在我们的数据库中存在一个大表,或多或少是这样的:

CREATE TABLE dbo.production_data
(
    pd_id BIGINT PRIMARY KEY,
    serial NVARCHAR(16) NOT NULL UNIQUE,
    ...
);
Run Code Online (Sandbox Code Playgroud)

但是现在串行字段的大小变得很小,所以我想将其更改为 32。Visual Studio 模式比较工具建议通过以下方式执行此操作:

DROP INDEX ux_production_data_serial ON dbo.production_data;
GO
ALTER TABLE dbo.production_data ALTER COLUMN serial NVARCHAR(32) NOT NULL;
GO
CREATE INDEX ux_production_data_serial ON dbo.production_data(serial ASC);
Run Code Online (Sandbox Code Playgroud)

这真的需要吗?或者更像是这样做的超级保存方式?

另外在重新创建唯一索引时,我的表会被锁定吗?因为这将是一个大问题(因为该表有 3000 万行,我猜重新创建索引需要相当长的时间),因为下一个维护窗口是未来几个月。我的选择是什么?

index sql-server alter-table locking unique-constraint

14
推荐指数
1
解决办法
4万
查看次数

如何以线程安全的方式查询和增加值(计数器)?(避免竞争条件)

在每行有一个计数器(只是一个整数值)的表,我需要的电流值,并增加它在同一时间

实际上,我想这样做:

SELECT counter FROM table WHERE id=123
UPDATE table SET counter=counter+1 WHERE id=123
Run Code Online (Sandbox Code Playgroud)

但是这样做作为两个查询显然不是线程安全的:多个进程做同样的事情(在同一行)可能会得到相同的计数器值。我需要它们都是独一无二的,所以每个过程都会获得实际的当前值并将其增加一。

我可以想到一种结构,在其中我对每行实施手动锁定,但我想知道是否有更简单的方法来做到这一点?

mysql locking

14
推荐指数
1
解决办法
3万
查看次数