Материал: Using_MySql,_MS_SQL_Server_and_Oracle

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Пример 41: управление неявными транзакциями

в конфигурационном файле).

Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 435/545

Пример 41: управление неявными транзакциями

Для решения данной задачи в MySQL необходимо использовать следующий набор запросов.

Решение 6.1.1 .а

1— Автоподтверждение выключено:

2SET autocommit = 0;

3

 

 

4

SELECT COUNT(*)

5

FROM

'subscribers'; — 4

6

 

 

7

INSERT INTO 'subscribers'

8

 

('s name')

9

VALUES

('Иванов И.И.');

10

 

 

11SELECT COUNT(*)

12FROM 'subscribers'; — 5

14

ROLLBACK;

15

 

16SELECT COUNT(*)

17FROM 'subscribers'; — 4

18

19— Автоподтверждение включено:

20SET autocommit = 1;

21

22SELECT COUNT(*)

23FROM 'subscribers'; — 4

25INSERT INTO 'subscribers'

26

 

('s name')

27

VALUES

('Иванов И.И.');

28

 

 

29SELEcT COUNT(*)

30FROM 'subscribers'; — 5

31

32 ROLLBACK;

33

34SELECT COUNT(*)

35FROM 'subscribers'; — 5

Встроках 1-17 запросы выполняются в режиме отключённого автоподтверждения неявных транзакций: именно поэтому отмена транзакции в строке 14 проходит успешно и вставка данных, выполненная в строках 7-9, аннулируется.

Встроках 19-35 запросы выполняются в режиме включённого автоподтверждения неявных транзакций, и потому отмена транзакции в строке 32 ни на что не влияет: вставка данных, выполненная в строках 25-27, остаётся в силе.

MS SQL Server (как и MySQL) по умолчанию работает с включённым автоподтверждением неявных транзакций, т.е. любые изменения данных сразу же вступают в силу. За изменение данного поведения отвечает параметр IM-

PLICIT_TRANSACTIONS (которым в общем случае можно управлять только ло-

кально на протяжении сессии; общие идеи по управлению этим параметром на уроне настроек описаны здесь31).

Для решения данной задачи в MS SQL Server необходимо использовать следующий набор запросов. Обратите внимание, что параметр IMPLICIT_TRANSAC- TIONS в MS SQL Server по своей логике противоположен параметру autocommit в MySQL (т.е. для выключения автоподтверждения неявных транзакций необходимо

31https://msdn.microsoft.com/en-us/library/ms176031 %28SQL.90%29.aspx

Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 436/545

Пример 41: управление неявными транзакциями

выполнить команду SET IMPLICIT_TRANSACTIONS ON).

Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 437/545

Пример 41: управление неявными транзакциями

MS SQL І Решение 6.1.1.a

1-- Автоподтверждение выключено:

2SET IMPLICIT TRANSACTIONS ON;

4

SELECT COUNT(*)

5

FROM

[subscribers]; -- 4

6

 

 

7

INSERT INTO [subscribers]

8

 

([s name])

9

VALUES

(N'Иванов И.И.');

10

 

 

11SELECT COUNT(*)

12FROM [subscribers]; -- 5

14

ROLLBACK;

15

 

16SELECT COUNT(*)

17FRoM [subscribers]; -- 4

19-- Автоподтверждение включено:

20 SET IMPLICIT TRANSACTIONS OFF;

21

22SELECT COUNT(*)

23FRoM [subscribers]; -- 4

25INSERT INTO [subscribers]

26

 

([s name])

27

VALUES

(N'Иванов И.И.');

28

 

 

29SELECT COUNT(*)

30FRoM [subscribers]; -- 5

32ROLLBACK; — Ошибка! Нет соответствующей транзакции, которую

33 — можно было бы отменить.

34

35 SELECT COUNT(*)

36 FROM [subscribers]; -- 5

Встроках 1-17 запросы выполняются в режиме отключённого автоподтверждения неявных транзакций: именно поэтому отмена транзакции в строке 14 проходит успешно и вставка данных, выполненная в строках 7-9, аннулируется.

Встроках 19-36 запросы выполняются в режиме включённого автоподтверждения неявных транзакций, и потому отмена транзакции в строке 32 ни на что не влияет: вставка данных, выполненная в строках 25-27, остаётся в силе.

В MS SQL Server существует одна важная особенность, которую необходимо учитывать. Если в режиме IMPLICIT_TRANSACTIONS ON использовать выражение BEGIN TRANSACTION, СУБД читает созданную транзакцию вложенной (@@TRANCOUNT принимает значение 2) и для успешного подтверждения её выполнения необходимо использовать выражение COMMIT TRANSACTION дважды. В противном случае вы рискуете или по-

лучить «подвисшую» транзакцию (которая так и не завершена), или потерять результаты модификации данных (если закроете соединение с СУБД). При этом ROLLBACK TRANSACTION работает в обоих режимах

одинаково, отменяя все транзакции вне зависимости от глубины их вложенности.

Эта проблема усугубляется тем, что при отладке запросов в средствах наподобие MS SQL Server Management Studio вы, как правило, работаете в рамках одного и того же соединения, и вместо «подвисшей» транзакции получаете продол

Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 438/545

Пример 41: управление неявными транзакциями

жение предыдущей (не закрытой ранее). Потому в большинстве случаев при отладке всё работает правильно, а в реальных приложениях поведение становится неверным.

Продемонстрируем только что описанное поведение MS SQL Server.

Решение 6.1.1 .а (демонстр

Режим по умолчанию

2 SET IMPLICIT_TRANSACTIONS OFF;

3 PRINT @@TRANCOUNT; — 0

5 BEGIN TRANSACTION;

4 -- Старт первой ("родительской") транзакции

6PRINT @@TRANCOUNT; — 1

7-- Старт второй ("дочерней") транзакции

8BEGIN TRANSACTION;

9PRINT @@TRANCOUNT; — 2

10-- Подтверждение второй ("дочерней") транзакции

11COMMIT TRANSACTION;

12PRINT @@TRANCOUNT; — 1

13-- Подтверждение первой ("родительской") транзакции

14COMMIT TRANSACTION;

 

15

PRINT @@TRANCOUNT; — 0

17

16

 

 

18

-- Режим "неявных транзакций" SET

IMPLICIT_TRANSACTIONS ON;

19

PRINT @@TRANCOUNT;

0

 

20-- Старт первой ("родительской") транзакции BEGIN TRANSACTION;

21PRINT @@TRANCOUNT; 2

22-- Старт второй ("дочерней") транзакции BEGIN TRANSACTION;

23PRINT @@TRANCOUNT; — 3

24-- Подтверждение второй ("дочерней") транзакции COMMIT TRANSACTION;

25PRINT @@TRANCOUNT; — 2

26-- Подтверждение первой ("родительской") транзакции COMMIT TRANSACTION;

27

PRINT @@TRANCOUNT;

1

 

28

-- Необходим ещё и этот COMMIT COMMIT TRANSACTION;

 

29

PRINT @@TRANCOUNT;

0

 

30

 

 

 

 

 

31

--

Режим

по умолчанию

 

 

32

SET IMPLICIT_TRANSACTIONS OFF;

 

33

--

Старт

 

первой ("родительской")

транзакции

34

BEGIN TRANSACTION;

 

 

35

PRINT @@TRANCOUNT;

1

 

36-- Старт второй ("дочерней") транзакции BEGIN TRANSACTION;

37PRINT @@TRANCOUNT; — 2 -- Отмена всех транзакций ROLLBACK TRANSACTION;

38

PRINT @@TRANCOUNT;

0

 

39

 

 

 

40

-- Режим "неявных транзакций" SET IMPLICIT_TRANSACTIONS ON;

41

-- Старт

первой ("родительской")

транзакции

42BEGIN TRANSACTION;

43PRINT @@TRANCOUNT; 2

44-- Старт второй ("дочерней") транзакции BEGIN TRANSACTION;

45PRINT @@TRANCOUNT; — 3 -- Отмена всех транзакций ROLLBACK TRANSACTION;

46 PRINT @@TRANCOUNT;

0

47

48

49

50

51

52

53

54

55

56

57

58

Работа с MySQL, MS SQL Server и Oracle в примерах © Богдан Марчук Стр: 439/545

Источник: https://studfile.net/preview/16420333/