【问题标题】:SQL, how to test concurrent transactionsSQL,如何测试并发事务
【发布时间】:2016-05-02 13:13:19
【问题描述】:

假设有一个表 something 与列 id, foo, bar, baz, qux, norf, updated_at 并且想要测试当涉及在该表上工作的并发事务时可能发生的各种用例,例如:

用例:如果您检查以下事务 T1T2,例如如何测试从 插入的事务隔离级别>T2 将在第二个 SELECT 中可用,假设 T2 将在 T1 中的第一个和第二个 SELECT 之间提交?

所以我想在这里测试phantom read 的一些变体,尽管 SELECT 语句不同 ?

我唯一的想法是在两个 SELECT 语句之间使用 SELECT PG_SLEEP(N); 并打开两个数据库连接(例如某些数据库客户端的 2 个实例,例如 PgAdmin),一个用于处理 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,但我正在使用 mysqlsql-server,因为问题与它们都不相关。

我还检查了已经提出的问题:
How to test MySQL transactions?
How to test concurrency locally?

【问题讨论】:

  • 你真的在这里使用 MySQL 和 SQL Server 和 Postgresql 吗?不要标记未涉及的产品...

标签: mysql sql sql-server postgresql transactions


【解决方案1】:

对于 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;

【讨论】:

  • 我很接近,但到目前为止,谢谢你的解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 2020-07-08
相关资源
最近更新 更多