Mik*_*rey 7 sql db2 multithreading identity sequence
我正在研究一个使用DB2作为其主数据库的多线程应用程序.在过去,我们主要使用Identity列表,我们需要一个自动生成的唯一标识符.为此,我们将在同一事务中运行以下2个查询:
INSERT INTO tbname (IDENTITY_COL, ...) VALUES (DEFAULT, ...);
SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1;
Run Code Online (Sandbox Code Playgroud)
我们现在被迫改为切换到Sequence.我知道你可以在INSERT和SELECT语句中使用"NEXT VALUE FOR colname ",但是我无法弄清楚INSERT和SELECT如何使用相同的值而不会在多线程应用程序中冒着竞争条件的风险.例如,如果我使用:
INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...);
SELECT PREVIOUS VALUE FOR SEQUENCE_COL;
Run Code Online (Sandbox Code Playgroud)
然后有可能在上面的INSERT和SELECT之间运行另一个INSERT,因此为我提供了不正确的值.如果我尝试:
SELECT NEXT VALUE FOR SEQUENCE_COL;
Run Code Online (Sandbox Code Playgroud)
将值存储在变量中并将其传递给INSERT:
INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...);
Run Code Online (Sandbox Code Playgroud)
然后有可能另一个线程获得相同的NEXT VALUE并尝试插入相同的值,从而导致DB2 -803错误.是否可以在多线程环境中使用SEQUENCE列,或者我是否需要争取保留我的IDENTITY列?
除了Michael Sharek(正确)所说的:
INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (NEXT VALUE FOR SEQUENCE_COL, ...);
SELECT PREVIOUS VALUE FOR SEQUENCE_COL;
Run Code Online (Sandbox Code Playgroud)
你的假设然后有可能在上面的INSERT和SELECT之间运行另一个INSERT,因此为我提供了错误的值 "关于上述语句序列是不正确的.
"下一个值"和"前一个值"是特定于连接的.
从不同线程访问序列永远不会产生"竞争"条件.每个连接都有一个完全隔离的序列"环境".
你的问题中有一个错误的假设.
如果我尝试:
SELECT NEXT VALUE FOR SEQUENCE_COL;
Run Code Online (Sandbox Code Playgroud)
将值存储在变量中并将其传递给INSERT:
INSERT INTO tbname (SEQUENCE_COL, ...) VALUES (variable_value, ...);
Run Code Online (Sandbox Code Playgroud)
然后有可能另一个线程获得相同的NEXT VALUE并尝试插入相同的值
那不对.第二个线程将获得不同的NEXTVAL,并且与第一个线程的值不同.
我还想在这一部分加上我的意见:
我们现在被迫改为切换到Sequence.
我无法想象有一个很好的理由从身份切换到序列.它们基本上是一回事.