C# для профессионалов. Том II
Шрифт:
В блоке
try
, если все идет хорошо, или, другими словами, если поток выполнения должен покинуть PlaceOrder
нормально, через return true
, инструкция PlaceOrder
вызывает метод SetComplete
объекта ContextUtil
, эффективно сообщая DTC через менеджер ресурсов, что в той части, которая касается его, транзакцию необходимо зафиксировать. С другой стороны, если где-то в
PlaceOrder
возникает ошибка и порождается исключение, управление программой будет передано
catch
. В этом предложении PlaceOrder
вызовет метод SetAbort
объекта ContextUtil
. Этот метод посылает голос PlaceOrder
за отмену транзакции, в которую он вовлечен, и DTC после получения этого голоса от менеджера ресурсов прикажет каждому участнику транзакции отменить свою работу. Помните, что не требуется создавать экземпляр объекта
ContextUtil
, чтобы вызвать его методы SetComplete
и SetAbort
. Эти методы класса, поэтому их можно вызывать прямо на классе. Практически любой код, поддерживающий транзакции будет походить на код в примере. Он вызывает
SetComplete
перед своей точкой выхода для фиксации всей работы, которая была успешно выполнена, или он вызывает метод SetAbort
класса ContextUtil
в своем обработчике ошибок, чтобы все отменить в связи с ошибкой. Существует, правда, еще более простой способ. Компания Microsoft предоставляет атрибут .NET, называемый
AutoComplete
. Методы, модифицированные с помощью этого атрибута, автоматически применяют подход, описанный выше. И хотя такие методы никогда явно не ссылаются на класс ContextUtil
, они неявно завершают свои транзакции, если те заканчиваются нормально, или отменяют всю работу если выход происходит в связи с ошибкой (когда порождается исключение). По прежнему необходимо вызывать SetAbort
, чтобы отменить работу транзакции если порождается исключение. [AutoComplete]
public bool PlaceOrder(bool CommitTrans) {
try {
if (CommitTrans) {
// Эта транзакция должна быть зафиксирована
// шаг 1 — Увеличить число единиц продукта ID=2 на 10
IncreaseUnits(2, 10);
// шаг 2 - Сократить запас продукта ID=2 на 10 единиц
ReduceStock(2, 10);
} else {
// Эта транзакция должна быть отменена
// шаг 1 - Увеличить число единиц продукта ID=5 на 5
IncreaseUnits(5, 5);
// шаг 2 — Сократить запас продукта ID=5 на 5 единиц
ReduceStock(5, 5);
}
return true;
} catch (Exception e) {
ContextUtil.SetAbort;
return false;
}
}
Это
using System;
using System.EnterpriseServices;
using System.Data.SqlClient;
namespace OrderTransaction {
[Transaction(TransactionOptiоn.Required)]
public class Purchase : ServicedComponent {
public Purchase { }
public bool PlaceOrder(bool CommitTrans) {
// Попытка работы
try {
if (CommitTrans) {
// Эта транзакция должна быть зафиксирована
// шаг 1 - Увеличить число единиц продукта ID=2 на 10
IncreaseUnits(2, 10);
// шаг 2 - Сократить запас продукта ID=2 на 10 единиц
ReduceStock(2, 10);
} else {
// Эта транзакция должна быть отменена
// шаг 3 — Увеличить число единиц продукта ID=5 на 5
IncreaseUnits(5, 5);
// шаг 2 — Сократить запас продукта ID=5 на 5
единиц ReduceStock(5, 5);
}
// Если все прошло хорошо, закончить транзакцию.
ContextUtil.SetComplete;
return true;
}
// Этот код выполняется, если встречается ошибка.
catch (Exception e) {
// Отменить работу, которую выполнила эта функция.
ContextUtil.SetAbort;
return false;
}
}
public void ReduceStock(int ProductID, int amount) {
string source = "server ephemeral;uid=sa;pwd=garysql;database Northwind";
SqlConnection conn = new SqlConnection(source);
string command =
"UPDATE Products SET UnitsInStock = UnitsInStock - " +
amount.ToString + " WHERE ProductID = " + ProductID.ToString;
conn.Open;
sqlCommand cmd = new SqlCommand(command, conn);
cmd.ExecuteNonQuery;
conn.Close;
}
public void IncreaseUnits(int ProductID, int amount) {
Поделиться:
Популярные книги
Последнее желание
1. Ведьмак
Фантастика:
фэнтези
9.43
рейтинг книги
Ученичество. Книга 2
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Адвокат Империи 7
7. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Вонгозеро
1. Вонгозеро
Детективы:
триллеры
9.19
рейтинг книги
Мастер 7
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Неудержимый. Книга IX
9. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Двойник Короля 2
2. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Сумеречный Стрелок 2
2. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 7
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
На границе империй. Том 8. Часть 2
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
И вспыхнет пламя
2. Голодные игры
Фантастика:
социально-философская фантастика
боевая фантастика
9.44
рейтинг книги
Кодекс Крови. Книга I
1. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неучтенный. Дилогия
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Черный Маг Императора 10
10. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00