当使用数据库服务器存储货币/金融数据时,我只能假设使用交易是强制性的。
但我不确定通常的隔离级别是哪个?是READ-REPEATABLE二手的吗?还是只有序列化级别?
我有这张桌子
create table testing(
c1 text,
c2 text);
Run Code Online (Sandbox Code Playgroud)
我同时打开两笔交易。t0 t1..表示按递增顺序排列的一系列时间快照 事务 1
BEGIN; -- t0
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- t2
SELECT * FROM testing where c2 = 'rand'; -- t4
INSERT INTO testing VALUES ('rand', 'xyz'); -- t6
COMMIT; -- t8
Run Code Online (Sandbox Code Playgroud)
交易2
BEGIN; -- t1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; -- t3
SELECT * FROM testing where c1 = 'rand1'; -- t5
INSERT INTO testing VALUES ('rand1', 'abc'); -- t7
COMMIT; -- t9
Run Code Online (Sandbox Code Playgroud)
t9当我收到这个错误
后 …
文档中指出:
仅当记录完全填充后才会发生重复验证。在某些情况下,这可能会导致在创建过程中将同一个编号用于多个记录,但随后会被识别为重复项
我不想在像这样的插入查询中使用该数字:
INSERT Test.Orders (OrderID, Name, Qty)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2) ;
Run Code Online (Sandbox Code Playgroud)
我想在我的网络应用程序中获取该数字并使用它来构造密文。并将加密后的代码存储在数据库中。因此,就我而言,插入时没有重复检查。
我需要知道的是,两个客户端是否有可能NEXT VALUE FOR几乎同时调用函数并获得相同的值?或不?(我需要不要发生这种情况)
我们最近从 LogShippingstandby/read-only设置迁移到具有可读辅助设备的多子网 AG 设置。
通常,在旧设置中,我们会选择运行较长时间的查询,因为相关数据库超过 20 TB,并且主数据库上有混合读写工作负载。
在转移到 AG 的新设置后,我们开始看到我无法理解的阻塞。为什么辅助选择查询会阻止我的可读辅助副本实例中的其他选择查询,即使正在查询的数据库有RCSI enabled?
以下是我捕获的内容
主要阻止程序是一些长时间运行的SELECT查询,不会显示任何特定的等待类型,例如 SPID129
SPID 129阻止会话 ID 45(我确信这不是用户 ID)近 6 小时,这取决于 spid129 并且等待类型是
LCK_M_SCH_M
SPID 45当这在 6 小时的持续时间内阻止所有其他选择查询时,问题就来了。
我无法理解发生了什么。有人可以帮助我排除故障或寻找正确的方向吗?
sql-server isolation-level availability-groups blocking sql-server-2017
我需要获取MAX交易中某个字段的聚合。我在事务中进一步使用此值。我想避免在整个表中插入,而我正在从中获取MAX事务完成时。
我研究了可用的隔离模式和锁定提示。最接近的似乎是TABLOCKX,这是唯一避免在整个表中插入(也更新和选择)的方法。
由于我不会受到表中更新或选择的影响,我希望避免在事务期间仅插入。这个有可能?
更新:执行的字段MAX仅在插入时设置,因此没有获得更新结果过时的风险。
我正在使用 SQL Server 2000。
PostgreSQL 是否提供内置的乐观并发控制机制,例如 SQL Server 的读提交快照隔离?读者可以在不阻塞的情况下读取所有行,但如果在事务期间修改了行,则写入将阻塞并失败。
编辑:在 RCSI 下,写入实际上不会“阻塞并失败”,而只是阻塞。
“可序列化”意味着对于任何给定的并发事务集,这些事务的串行排序会产生相同的结果。
他们还举了一个例子
假设您有一个初始值为 10 的属性;你有两笔交易——一笔使价值翻倍,另一笔增加了七笔。两个不同的客户端发起两个事务。在孤立语义下,该属性唯一可接受的值是 27(先加倍后加 7 的结果)和 34(先加 7 后加倍的结果)。任何其他值(例如 20 或 17)都将是错误的。
在示例中我们有哪个“相同的结果”?我们必须进行哪些重新排序才能产生相同的结果?
我刚刚读完隔离级别的优秀文章在这里。我们公司将很快开始对我们当前产品的重写和扩展开发。我的愿望是拥有一个 OLTP 数据库和一个单独的、更加非规范化的报告数据库。假设我们有一定的纪律性,并且我们的大多数临时和报告类型查询实际上都转到报告数据库,那么我们的 OLTP 数据库具有读取提交的默认隔离级别(我们不需要更严格的隔离级别)听起来合适吗? OLTP 级别)和我们的报告数据库是快照隔离(可能是 RCSI)?
我的想法是,如果我们的 OLTP 数据库实际上是一个真正的 OLTP 数据库并且不作为报告数据库提供双重职责,我们将不需要快照隔离及其相关的开销。但是快照隔离在报告数据库上是可取的,这样读者就不会被不断传入的数据流阻塞,并且读取最后保存的行版本是可以接受的。
我的数据库的默认隔离级别是“读提交快照”。请看下面的截图。
我的数据库中有包含以下数据的“门票”表。
现在在连接 1 中,我正在启动一个隔离级别为“已提交读”的新事务。我要将#TicketID“2”的优先级更新为“中等”
从连接 2,我试图访问 #TicketID "2" 的详细信息。并且它仍然从由读取提交的快照隔离创建的版本存储中获取值,这不是预期的行为。
根据文档,如果事务使用“读提交”隔离级别,则在事务执行提交/回滚之前,任何其他事务都无法访问该行。
谁能告诉我为什么在给定的情况下它没有发生?我也很想知道,为什么事务级别的隔离不能覆盖在数据库级别设置的默认隔离级别(这里是读取提交的快照)?
为了更清楚地说明事务范围上的隔离覆盖,我提供了以下信息。
我已将数据库隔离设置为已提交读。
现在在连接 1 中,我正在启动我的事务以更新票证优先级。
在连接 2 中,我正在尝试访问记录。但这不会完成,因为事务隔离级别处于“读提交”模式。
在连接 3 中,我试图访问隔离级别为“未提交读取”的记录。在这里我们可以看到记录,因为它将覆盖在数据库级别设置的默认隔离。
当我在数据库级别设置“快照隔离”并在另一个事务范围内覆盖它时,我期待相同的行为。对我来说,它总是从版本存储中返回最后提交的值,而不管事务范围中提到的隔离级别如何。我希望我清楚地表达了我的担忧.. :)
我想查看正在进行事务的表中的数据。我将使用这个超级简单的临时表作为示例:
SELECT 5 AS NUMBER INTO ##temptable
Run Code Online (Sandbox Code Playgroud)
我将创建一个事务来插入数字为 10 的新行:
BEGIN TRAN;
INSERT INTO ##temptable
SELECT 10 AS Number
WAITFOR DELAY '00:00:20';
COMMIT TRAN;
Run Code Online (Sandbox Code Playgroud)
现在,如果我打开一个新查询,并执行常规 select 语句,我将不会得到任何结果,轮子将一直旋转,直到事务提交。我可以将隔离级别设置为已提交读:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Run Code Online (Sandbox Code Playgroud)
我希望这会返回已提交的数字 5,但不会返回未提交的数字 10,但我再次得到一个旋转轮。我想事情并不是这样的。
如果我将隔离级别设置为读取未提交:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Run Code Online (Sandbox Code Playgroud)
这成功地从表中返回两个数字。
但我仍然有一个问题,因为我想在事务内部创建表,如下所示:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN;
SELECT 5 AS NUMBER INTO ##temptable
INSERT INTO ##temptable
SELECT 10 AS Number
WAITFOR DELAY '00:00:20';
COMMIT TRAN;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果我尝试从表中读取数据,即使将隔离级别设置为读取未提交的数据,我也会再次陷入困境。
有什么方法可以从正在进行的事务中创建的表中读取数据吗?
isolation-level ×10
sql-server ×6
transaction ×3
concurrency ×2
postgresql ×2
blocking ×1
consistency ×1
hints ×1
locking ×1
mysql ×1
sequence ×1
terminology ×1