从 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 错误的其他原因:
- 试图
CREATE或DROP表或索引而SELECT声明仍悬而未决。- 当 a
SELECT在同一张表上处于活动状态时尝试写入表。- 尝试
SELECT在多线程应用程序中同时在同一张表上执行两个操作,如果 sqlite 未设置为这样做。- fcntl(3,F_SETLK 对 DB 文件的调用失败。例如,这可能是由 NFS 锁定问题引起的。此问题的一种解决方案是将 DB 移走,然后将其复制回来,使其具有新的 Inode 值
所以,我想为自己澄清一下,有必要避免锁吗?我可以从两个不同的线程同时读取和写入吗?谢谢。
在我们的数据库中存在一个大表,或多或少是这样的:
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 万行,我猜重新创建索引需要相当长的时间),因为下一个维护窗口是未来几个月。我的选择是什么?
SQL Server 2008 R2 中是否有办法导致涉及事务的数据库修改超时?我们有一个场景,我们的应用程序代码挂起或抛出异常并且无法执行回滚或提交。这会导致其他会话挂起等待事务完成。
我试图了解如何最好地解释我们的 MySQL 慢查询日志中显示的查询的锁定时间。
例如,如果 UPDATE 查询有 10 秒的锁定时间。我认为这是更新查询获取锁后的总时间。即使它正在等待先前的选择查询完成但不执行 UPDATE 操作本身,时钟也应该在滴答作响,因为它正在锁定在 UPDATE 查询之后排队的所有 SELECT 查询。
以及 SELECT 查询锁怎么样。为什么一些选择查询有锁定时间?是不是因为有一个 UPDATE 查询跟进,因此他们将一个表锁定在一起。
如何在 MySQL 中正确实现乐观锁?
我们的团队推断我们必须执行下面的 #4,否则存在另一个线程可以更新记录的相同版本的风险,但我们想验证这是最好的方法。
SELECT FOR UPDATE对我们要更新的记录执行 a ,以便我们序列化谁可以对我们尝试更新的记录进行更改。为了澄清起见,我们试图阻止在同一时间窗口中选择相同记录的两个线程,如果它们同时尝试更新记录,则它们会在其中获取相同版本的记录时相互覆盖。我们相信,除非我们做 #4,否则有可能,如果两个线程同时进入各自的事务(但尚未发布更新),当它们进行更新时,第二个线程将使用 UPDATE ...其中 version = X 将对旧数据进行操作。
即使我们使用版本字段/乐观锁定,我们在更新时也必须执行这种悲观锁定的想法是否正确?
我正在解决一个死锁问题,同时我注意到当我在 id 字段上使用聚集和非聚集索引时,锁定行为是不同的。如果将聚集索引或主键应用于 id 字段,则死锁问题似乎已解决。
我有不同的事务对不同的行进行一次或多次更新,例如事务 A 只会更新 ID=a 的行,tx B 只会接触 ID=b 的行等。
而且我了解到,如果没有索引,更新将获取所有行的更新锁,并在必要时转换为排他锁,这最终会导致死锁。但是我没有找到为什么使用非聚集索引,死锁仍然存在(虽然命中率似乎下降了)
数据表:
CREATE TABLE [dbo].[user](
[id] [int] IDENTITY(1,1) NOT NULL,
[userName] [nvarchar](255) NULL,
[name] [nvarchar](255) NULL,
[phone] [nvarchar](255) NULL,
[password] [nvarchar](255) NULL,
[ip] [nvarchar](30) NULL,
[email] [nvarchar](255) NULL,
[pubDate] [datetime] NULL,
[todoOrder] [text] NULL
)
Run Code Online (Sandbox Code Playgroud)
死锁跟踪
deadlock-list
deadlock victim=process4152ca8
process-list
process id=process4152ca8 taskpriority=0 logused=0 waitresource=RID: 5:1:388:29 waittime=3308 ownerId=252354 transactionname=user_transaction lasttranstarted=2014-04-11T00:15:30.947 XDES=0xb0bf180 lockMode=U schedulerid=3 kpid=11392 status=suspended spid=57 sbid=0 ecid=0 priority=0 trancount=2 lastbatchstarted=2014-04-11T00:15:30.953 lastbatchcompleted=2014-04-11T00:15:30.950 lastattention=1900-01-01T00:00:00.950 clientapp=.Net SqlClient Data …Run Code Online (Sandbox Code Playgroud) 查询执行计划默认不显示锁定详细信息,是否可以查看在查询执行期间获取的锁定以及类型?
我有一对查询,在可序列化隔离下,会导致 RX-X 锁定。但是,当我使用扩展事件查看锁获取时,RX-X 锁获取从未出现,它只是释放。它从何而来?
这是我的表:
CREATE TABLE dbo.LockTest (
ID int identity,
Junk char(4)
)
CREATE CLUSTERED INDEX CX_LockTest --not unique!
ON dbo.LockTest(ID)
--preload some rows
INSERT dbo.LockTest
VALUES ('data'),('data'),('data')
Run Code Online (Sandbox Code Playgroud)
这是我的问题批次:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
INSERT dbo.LockTest
VALUES ('bleh')
SELECT *
FROM dbo.LockTest
WHERE ID = SCOPE_IDENTITY()
--ROLLBACK
Run Code Online (Sandbox Code Playgroud)
我检查了这个会话持有的锁,并看到了 RX-X:
SELECT resource_type, request_mode, request_status, resource_description
FROM sys.dm_tran_locks
WHERE request_session_id = 72 --change SPID!
Run Code Online (Sandbox Code Playgroud)
但我在lock_acquired和上也有一个扩展事件lock_released。我在适当的 associated_object_id 上过滤它...没有 RX-X。
执行回滚后,我看到 RX-X (LAST_MODE) 被释放,即使它从未被获取。 …
我有两个问题:
1. 为什么在这种情况下会出现更新冲突而不是阻塞:
-- prepare
drop database if exists [TestSI];
go
create database [TestSI];
go
alter database [TestSI] set READ_COMMITTED_SNAPSHOT ON;
alter database [TestSI] set ALLOW_SNAPSHOT_ISOLATION ON;
go
use [TestSI];
go
drop table if exists dbo.call_test;
create table dbo.call_test ( Id bigint CONSTRAINT [PK_Call] PRIMARY KEY CLUSTERED ( [Id] ASC ), additional int, incl int );
create index ix_Call on dbo.call_test ( additional ) include( incl );
insert into dbo.call_test select 1, 2, 3;
go
Run Code Online (Sandbox Code Playgroud)
第一节:
use [TestSI];
go
set …Run Code Online (Sandbox Code Playgroud) sql-server database-internals locking snapshot-isolation sql-server-2016
晚了,我一直面临着很多行锁争用。争用的表似乎是一个特定的表。
一般是这样的——
大约 5 分钟后,前端似乎没有响应。检查会话显示行锁争用。每个人都抛出的“解决方案”是终止会话:/
作为数据库开发人员
如果这个问题感觉过于开放/信息不足,请随时编辑/让我知道 - 我会尽力添加一些额外的信息。
有问题的表有很多插入和更新,我想说它是最繁忙的表之一。SP 相当复杂 - 为简化起见 - 它从各种表中获取数据,将其填充到工作表中,在工作表上发生大量算术运算,并将工作表的结果插入/更新到相关表中。
数据库版本为 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit。逻辑流在两个会话中以相同的顺序执行,事务不会保持打开太长时间(或者至少我认为是这样),并且在事务的主动执行期间发生锁定。
更新:表格行数比我预期的要大,大约有 310 万行。此外,在跟踪会话后,我发现该表的几个更新语句没有使用索引。为什么会这样 - 我不确定。where 子句中引用的列已编入索引。我目前正在重建索引。
locking ×10
sql-server ×4
index ×2
mysql ×2
alter-table ×1
oracle-10g ×1
sqlite ×1
transaction ×1