Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ? / 5 сообщений из 5, страница 1 из 1
14.06.2015, 01:47
    #38983380
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ?
hi all

Запустите у себя вот этот примерчик (а особо любопытные могут и трейс в отдельном окне; конечно, сначала надо подправить на свои host/port/path/file):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
shell del C:\FBTESTING\qa\fbt-repo\tmp\c4470.fdb 2>nul;
create database 'localhost/3333:C:\FBTESTING\qa\fbt-repo\tmp\c4470.fdb';

show version;
commit;

set autoddl on;
 commit; 

set bail on;
set echo on;
 create domain dm_dts as timestamp; 

 --set autoddl off; 

set term ^;
 execute block returns(dts dm_dts) as
begin
  dts = current_timestamp;
  suspend;
end 
^
set term ;^

Первый исполняемый оператор после "красного" коммита вызовет старт двух транзакций:
1) til = snapshot, для DML, и у неё будет номер = 7;
2) til = read committed, для DDL, и у неё будет номер = 8.

"Синенький" текст будет выполняться в транзакции с номером 8, причём сразу после окончания этого стейтмента будет тутже сделан commit:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
2015-06-14T01:23:28.5620 (1296:01884BC8) EXECUTE_STATEMENT_FINISH
	C:\FBTESTING\QA\FBT-REPO\TMP\C4470.FDB (ATT_3, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
	C:\1INSTALL\FIREBIRD\fb30sS\isql.exe:3032
		(TRA _8 , READ_COMMITTED | NO_REC_VERSION | WAIT | READ_WRITE)
-------------------------------------------------------------------------------
create domain dm_dts as timestamp
0 records fetched
      0 ms

2015-06-14T01:23:28.5780 (1296:01884BC8) COMMIT_TRANSACTION
	C:\FBTESTING\QA\FBT-REPO\TMP\C4470.FDB (ATT_3, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
	C:\1INSTALL\FIREBIRD\fb30sS\isql.exe:3032
		(TRA _8 , READ_COMMITTED | NO_REC_VERSION | WAIT | READ_WRITE)
      7 ms, 10 write(s), 21 fetch(es), 4 mark(s)

Изменение, т.е. новый домен в словаре базы, должны будут видеть:
1) все транзакции с TIL = RC, стартовавшие до этой DDL'ной tx = 8, если вздумают перечитать данные словаря;
2) только те транзакции с TIL = snapshot, которые стартуют после этого commit'a Tx = 8.

Транзакции с TIL = snapshot, имеющие Tx < 8, ни при каких обстоятельствах не должны видеть новый домен.

А теперь - внимание, знатоки, вопрос: почему вышеприведенный скрипт отрабатывает без ошибок, если в нём оставить закомментаренным set autoddl off; после create domain dm_dts as timestamp;
Я вижу в трейсе, что tx = 7, til = SNAPSHOT, спокойненько так юзает домен, который был создан в Tx = 8:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 [code=plaintext]2015-06-14T01:23:28.5780 (1296:01884BC8) EXECUTE_STATEMENT_FINISH
	C:\FBTESTING\QA\FBT-REPO\TMP\C4470.FDB (ATT_3, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
	C:\1INSTALL\FIREBIRD\fb30sS\isql.exe:3032
		(TRA _7, CONCURRENCY  | WAIT | READ_WRITE)

Statement 1310:
-------------------------------------------------------------------------------
execute block returns(dts dm_dts) as
begin
  dts = current_timestamp;
  suspend;
end

1 records fetched
...
Рейтинг: 0 / 0
14.06.2015, 01:57
    #38983382
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ?
PS. Разумеется, проверка того, что snapshot-транзакция не видит DDL-вставок до своего рестарта, показывает, что это действительно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
C:\FBTESTING\qa\fbt-repo\tmp>isql /3333:e30
Database:  /3333:e30
SQL> set list on;
SQL> select * from rdb$fields where rdb$system_flag=0;
SQL> create domain dm_dts timestamp; ------------------- это выполняется в tx2 c TIL = RC и тут же коммитится
SQL> select * from rdb$fields where rdb$system_flag=0; --- это выполняется в tx1 c TIL = SNAPSHOT
-- нет строк --
SQL> commit; -- закоммитили tx1
SQL> select * from rdb$fields where rdb$system_flag=0; -- и теперь, ес-сно, уже увидим:

RDB$FIELD_NAME                  DM_DTS
RDB$QUERY_NAME                  <null>
RDB$VALIDATION_BLR              <null>
RDB$VALIDATION_SOURCE           <null>
RDB$COMPUTED_BLR                <null>
RDB$COMPUTED_SOURCE             <null>
RDB$DEFAULT_VALUE               <null>
RDB$DEFAULT_SOURCE              <null>
RDB$FIELD_LENGTH                8
RDB$FIELD_SCALE                 0
RDB$FIELD_TYPE                  35
RDB$FIELD_SUB_TYPE              <null>
RDB$MISSING_VALUE               <null>
RDB$MISSING_SOURCE              <null>
RDB$DESCRIPTION                 <null>
RDB$SYSTEM_FLAG                 0
RDB$QUERY_HEADER                <null>
RDB$SEGMENT_LENGTH              <null>
RDB$EDIT_STRING                 <null>
RDB$EXTERNAL_LENGTH             <null>
RDB$EXTERNAL_SCALE              <null>
RDB$EXTERNAL_TYPE               <null>
RDB$DIMENSIONS                  <null>
RDB$NULL_FLAG                   <null>
RDB$CHARACTER_LENGTH            <null>
RDB$COLLATION_ID                <null>
RDB$CHARACTER_SET_ID            <null>
RDB$FIELD_PRECISION             <null>
RDB$SECURITY_CLASS              SQL$367
RDB$OWNER_NAME                  SYSDBA
...
Рейтинг: 0 / 0
14.06.2015, 10:08
    #38983408
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ?
в общем случае, уровень изоляции не распространяется на метаданные (их использование ядром)
...
Рейтинг: 0 / 0
14.06.2015, 10:40
    #38983417
Таблоид
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ?
пфф... кшмар.

А еще вот это как объяснить:
Код: plaintext
-- set autoddl off;

- если его раскомментарить, то вылезет вполне ожидаемая ошибка: транзакция-7 (snapshot!), выполняющая execute block, не видит результат коммита транзакции-8, выполнившей DDL 'create domain'.

Но как может влиять раскомментаривание "set audoddl off" на:
1) DML-транзакцию
2) на результат стетйтмента, который был запущен в (DML) транзакции, стартовавшей _до_ этого 'set autoddl off' ?!
...
Рейтинг: 0 / 0
14.06.2015, 11:53
    #38983429
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ?
при включенном AUTODDL все DML препарируются в контексте DDL-транзакции, а выполняются в контексте своей транзакции. При выключенном AUTODDL все DML и препарируются и выполняются в своей собственной транзакции.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как может Tx1 (TIL = SNAPSHOT) увидеть изменения от Tx2 (TIL = RC), где Tx2 > Tx1 ? / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]