2016-01-26 2 views
2

Допустим, что есть таблица something с колонками id, foo, bar, baz, qux, norf, updated_at, и каждый хочет протестировать различные варианты использования, которые могут возникать, когда речь идет о параллельных транзакциях, которые что-то работают в этой таблице, например:SQL, как тестировать параллельные транзакции

использования: проверив ниже операций T1 и T2, например, как для тестирования, при котором изоляции транзакций вставка уровня из T2 будет доступна во втором SELECT, при условии, что Т2 будет COMMIT betwee n первый и второй SELECT в T1?

Так что я тестирую здесь некоторый вариант phantom read. Я думаю, хотя операторы SELECT отличаются ?

Моя единственная идея состоит в том, чтобы использовать SELECT PG_SLEEP(N); между двумя ЗЕЬЕСТ и открыть два соединения DB (например, 2 экземпляра некоторого клиента БД, такие как PgAdmin) один для обработки T1 и один для обработки T2, чем вручную, чтобы начать T1 давая первый ВЫБРАТЬ закончить где PG_SLEEP(10) сгорит, чем вручную запустить T2, и в надежде увидеть набор результатов от T1 и сравнить его вручную. Но похоже, что это невозможно, потому что я не нашел ни одного клиента БД, который мог бы возвращать несколько наборов результатов из операторов 2+ 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 », потому что я хотел бы получить этот ответ от тестирования ,

Хотя я упоминал о постгреве на нескольких местах, я использую mysql и sql-server, потому что вопрос не привязан ни к одному из них.

Также я проверил уже предложенные вопросы:
How to test MySQL transactions?
How to test concurrency locally?

+0

Вы действительно используете MySQL и SQL Server и Postgresql здесь? Не помещайте продукты, которые не задействованы ... – jarlh

ответ

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; 
+0

Я был близок и все же до сих пор благодарю вас за отличное объяснение – Srle

Смежные вопросы