Шаг 46 - Метод BeginTrans, CommitTrans, Rollback

Описание
Данные методы позволяют управлять выполнением транзакции во время сеанса, определяемого объектом Workspace:

рабочаяОбласть.BeginTrans | CommitTrans [dbFlushOSCacheWrites] | Rollback

Параметры
рабочаяОбласть
Прототип рабочаяОбласть представляет объектную переменную, задающую объект Workspace, содержащий базы данных, которые используют транзакции.

Замечания
Данные методы объекта Workspace применяются в том случае, когда требуется выполнить как одну операцию ряд изменений, вносимых в базу данных в сеансе работы.
Как правило, транзакции используются для обеспечения целостности данных, когда требуется одновременно обновить записи в двух или нескольких таблицах и необходимо обеспечить, чтобы изменения были занесены во все таблицы (завершить транзакцию) или не были занесены ни в одну (свернуть транзакцию). Например, при переводе денег с одного счета на другой следует снять необходимую сумму с одного счета и добавить ту же сумму на другой счет. Если любая из операций обновления не будет выполнена, то баланс счетов будет нарушен. В подобном случае следует применить метод BeginTrans перед обновлением первой записи, а затем, если любое из последующих обновлений будет неудачным, применить метод Rollback для отмены всех обновлений. После успешного завершения последнего обновления следует применить метод CommitTrans для сохранения изменений.
В рабочей области Microsoft Jet пользователь имеет возможность задать в методе CommitTrans константу dbFlushOSCacheWrites. Это приводит к принудительной записи на диск всех обновлений вместо их помещения во временный буфер. Без этого параметра пользователь может перехватить управление сразу после вызова метода CommitTrans программой приложения, выключить компьютер, и отказаться от записи данных на диск. Хотя включение данного параметра может сказаться на быстродействии приложения, это оказывается полезным в ситуациях, когда возможно отключение компьютера до сохранения на диске кэшированных изменений.
В пределах одного объекта Workspace транзакции всегда являются глобальными и не ограничиваются только одним объектом Connection или Database. Если операции транзакции проводились в пределах одного сеанса работы над несколькими подключениями или базами данных в объекте Workspace, то разрешение транзакции (т.е. вызов метода CommitTrans или Rollback) затрагивает все операции для всех подключений и баз данных в этой рабочей области.
После вызова метода CommitTrans отмена внесенных во время транзакции изменений становится невозможной за исключением случая, когда данная транзакция была вложена в другую транзакцию, которую можно свернуть. При использовании вложенных транзакций необходимо разрешить текущую транзакцию до разрешения транзакции высшего уровня вложенности.
Если требуется одновременно выполнять несколько независимых (не вложенных) перекрывающихся транзакций, то следует создать дополнительные объекты Workspace, которые будут содержать конкурирующие транзакции.
Если объект Workspace будет закрыт без явного завершения или отмены открытых транзакций, то транзакции будут автоматически свернуты.
Попытка вызвать методы CommitTrans или Rollback без предварительного вызова метода BeginTrans приводит к ошибке.
Некоторые базы данных ISAM, используемые в рабочей области ядра Microsoft Jet, могут не поддерживать транзакции. В этом случае свойство Transactions объекта Database или Recordset получает значение False. Для того чтобы проверить, поддерживает ли база данных транзакции, следует проверить значение свойства Transactions объекта Database перед вызовом метода BeginTrans. При работе с объектом Recordset, содержащим записи из нескольких баз данных, следует проверить значение свойства Transactions объекта Recordset. Если объект Recordset создан только на основе таблиц Microsoft Jet, то транзакции всегда возможны. Объекты Recordset, базирующиеся на таблицах, созданных в других СУБД, могут не поддерживать транзакции. Например, не допускается выполнение транзакций для объекта Recordset, созданного на основе таблицы Paradox. В этом случае свойство Transactions имеет значение False. Если объекты Database или Recordset не поддерживают транзакции, то вызовы методов управления транзакциями игнорируются и ошибка не возникает.
Вложенные транзакции нельзя использовать при работе с источниками данных ODBC с помощью ядра базы данных Microsoft Jet.
Объединение операций с базой данных, требующих обращения к диску, в блоки транзакций часто позволяет повысить производительность приложения. Такой подход обеспечивает буферизацию операций и может сильно уменьшить число обращений к диску.
В рабочей область ядра Microsoft Jet транзакции регистрируются в файле, который сохраняется в каталоге, указанном в переменной среды TEMP, определенной для данной рабочей станции. Если файл журнала транзакций исчерпывает доступное пространство на диске, на котором находится каталог TEMP пользователя, ядро базы данных генерирует ошибку выполнения. В таком случае при вызове метода CommitTrans результаты некоторых операций окажутся занесенными, а результаты остальных незавершенных операций будут потеряны. Это делает необходимым повторение операции. Вызов метода Rollback освобождает файл журнала транзакций и свертывает все операции транзакции.

Пример
Следующая программа изменяет в таблице "Сотрудники" название должности всех коммерческих представителей. После запуска с помощью метода BeginTrans транзакции, в которой выделяются все изменения, вносимые в таблицу "Сотрудники", метод CommitTrans вызывается для сохранения изменений. Отметим, что метод Rollback позволяет отменить все изменения, занесенные с помощью метода Update. Более того, главная транзакция является вложенной в другую транзакцию, которая автоматически отменяет любые изменения, внесенные пользователем при работе с данным примером.
Пока пользователь решает, стоит или нет сохранять изменения, одна или несколько страниц таблицы остаются заблокированными. Поэтому данный прием не может быть рекомендован для использования и приводится только для иллюстрации.

Sub BeginTransX()

	Dim strName As String
	Dim strMessage As String
	Dim wrkDefault As Workspace
	Dim dbsNorthwind As Database
	Dim rstEmployees As Recordset

	' Определяет стандартный объект Workspace.
	Set wrkDefault = DBEngine.Workspaces(0)
	Set dbsNorthwind = OpenDatabase("Борей.mdb")
	Set rstEmployees = dbsNorthwind.OpenRecordset("Сотрудники")
	' Запускает внешнюю транзакцию.
	wrkDefault.BeginTrans
	' Запускает главную транзакцию.

wrkDefault.BeginTrans

	With rstEmployees

		' Выполняет цикл по набору записей и спрашивает пользователя,
		' следует ли изменять должность конкретного сотрудника.
		Do Until .EOF
			If !Должность = "Коммерческий представитель" Then
				strName = !Фамилия & ", " & !Имя
				strMessage = "Сотрудник: " & strName & vbCr & 	"Изменение должности"
				' Изменяет должность указанного сотрудника.
				If MsgBox(strMessage, vbYesNo) = vbYes Then
					.Edit
					!Должность = "Счетовод"
					.Update
				End If
			End If
			.MoveNext
		Loop
		' Запрашивает пользователя, следует ли занести
		' все ранее сделанные изменения.
		If MsgBox("Сохранить все изменения?", vbYesNo) = vbYes Then
			wrkDefault.CommitTrans
		Else
			wrkDefault.Rollback
		End If
		' Печатает текущие данные из набора записей.
		.MoveFirst
		Do While Not .EOF
			Debug.Print !Фамилия & ", " & !Имя & " - " & !Должность
			.MoveNext
		Loop
		' Отменяет все изменения, внесенные пользователем,
		' поскольку программа предназначена только для демонстрации.
		wrkDefault.Rollback
		.Close
	End With
	dbsNorthwind.Close
End Sub

Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.