假设有一个表 something
包含列 id, foo, bar, baz, qux, norf, updated_at
并且想要测试可以的各种用例当涉及到在此表上工作的并发事务时发生,例如:
用例:如果您检查以下事务T1 和T2,例如如何测试从插入的事务隔离级别>T2 将在第二个 SELECT 中可用,假设 T2 将在 T1?
中的第一个和第二个 SELECT 之间提交所以我想在这里测试一些幻读
的变体,尽管 SELECT 语句是不同的?
我唯一的想法是在两个 SELECT 语句之间使用 SELECT PG_SLEEP(N);
并打开两个数据库连接(例如某些数据库客户端的 2 个实例,例如 PgAdmin),其中一个用于处理 < strong>T1 和一个处理 T2 而不是手动启动 T1 让第一个 SELECT 完成 PG_SLEEP(10)
将触发的地方,而不是手动启动 T2,并希望看到 T1 的结果集并手动进行比较。但这似乎是不可能的,因为我没有找到任何可以从 2+ SELECT 语句返回多个结果集的数据库客户端。
(顺便说一下,使用一个 SELECT 而不是两个会很棒,以某种方式合并到一个 SELECT 但我不知道该怎么做)
T1:
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
...
SELECT sum(foo) as foo
FROM something
WHERE bar = 1 AND updated_at <= '...' AND norf = 2
UNION ALL
SELECT sum(foo)
FROM something
WHERE bar = 1 AND baz IN (1, 9, 10) AND updated_at > '...'
GROUP BY bar;
SELECT PG_SLEEP(10);
SELECT bar, qux, sum(foo) AS foo
FROM something
WHERE norf = 2
GROUP BY bar, qux;
COMMIT;
T2:
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
...
INSERT INTO something VALUES(...);
...
COMMIT;
请不要发布诸如“READ COMMITTED 是 postgre 中的默认事务级别,你不需要指定它”之类的答案,我只是作为一个例子使用它,或者“你将通过使用 REPEATABLE READ 来解决问题postgre”,因为我想从测试中得到答案。
虽然我在几个地方提到了 postgre,但我使用的是 mysql
和 sql-server
,因为问题与它们都不相关。
我还检查了已经提出的问题:
How to test MySQL transactions?
How to test concurrency locally?
最佳答案
对于 Sql Server,我通过在 Sql Server Management Studio 中打开两个不同的窗口来测试这种情况。每个窗口都有自己的数据库连接。然后,我逐步执行 T1 和 T2 的相关部分,以重现所需的测试用例。
我相信您可以使用其他数据库使用它们各自的工具来做一些非常相似的事情。
例子:
窗口 1
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
...
SELECT sum(foo) as foo
FROM something
WHERE bar = 1 AND updated_at <= '...' AND norf = 2
UNION ALL
SELECT sum(foo)
FROM something
WHERE bar = 1 AND baz IN (1, 9, 10) AND updated_at > '...'
GROUP BY bar;
窗口 2
START TRANSACTION;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
...
INSERT INTO something VALUES(...);
...
COMMIT;
窗口 1
SELECT bar, qux, sum(foo) AS foo
FROM something
WHERE norf = 2
GROUP BY bar, qux;
COMMIT;
关于mysql - SQL,如何测试并发事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35005959/