Каталог статей

Главная » Статьи » .NET

Манипулирование транзакциями между .NET компонентами
Нами будет рассмотрен вопрос о транзакциях, применимых как к Web-приложениям, так и к приложениям на базе Windows. 
Вопрос Я прочитал вашу колонку в выпуске (http://msdn.microsoft.com/msdnmag/issues/02/02/basics/default.aspx), посвященном COM+ , DCOM и MSMQ сериализации в .NET. Вы пишете, что если компонент выполняет транзакции над отдельной базой данных и вы предполагаете, что будете going against только одной базы данных, вам не обязательно требуется COM+, чтобы реализовать эти транзакции. Вы можете реализовать их с помощью ADO.NET. Это представляется серьезным изменением идеологии. 

Могли бы вы предоставить больше информации о том, как можно регулировать транзакции между .NET компонентами даже в том случае, если я имею дело с одной базой данных? Если я передаю connection string и сохраняю соединение (connection) открытым, не вызовет ли это издержек? 

Ответ. Для начала рассмотрим создание транзакций с помощью ADO.NET. Я создал пример приложения, которое вставляет от 1 до 4 order строк в таблицу Order Details в эталонной базе данных Northwind. Приложение использует SQL сервер и SQLClient провайдер данных. Практически то же самое можно сделать с помощью OLE DB провайдера в том случае, если ваша база данных поддерживает транзакции. 

Вместо того, чтобы просто сослаться на эталонный код транзакции в документации, поясняющей, как работают транзакции ADO.NET, мое эталонное приложение использует простой многоуровневый (multiplayer) подход. Весь код базы данных содержится в отдельном классе компонент (separate components class) в то время, как front end находится в Windows form в отдельном проекте. 

Компонент базы данных содержит один класс, которые именуется DBStuffDONET. Обратите внимание, что приватная переменная (private variable) содержит connection string. Это хорошо в том случае, когда компонент не требуется использовать с различными базами данных. Тем не менее, компонент имеет совмещенный конструктор (overloaded constructor), который принимает новую connection string, которая может специфицироваться, когда вы инстантиируете (instantiate) класс. 

После создания connection string variable я также создаю приватную переменную (private variable) для инстансов (Instances) SqlConnection и SqlTransaction. Детали будут рассмотрены позднее. 

Класс использует функцию RunSQLWithDataSet. Эта функция не участвует в транзакции, она возвращает транзакцию DataSet. В данном примере для простоты я использую статический SQL вместо хранимых процедур (stored procedures). 

Рассмотрим те функции, которые участвуют в транзакциях, а также некоторые из тех, которые не участвуют. Подпрограмма OpenConnectionTrans создает новый SqlConnection и затем открывает его. После этого он создает транзакцию базы данных, BeginTransaction и устанавливает переменную TransactionCurrent для ссылки (to reference) на транзакцию, как видно их данного примера: 

 
Public Sub OpenConnectionTrans()
  ConnectionCurrent = New SqlConnection(sConnectionString)
  ConnectionCurrent.Open()
  TransactionCurrent = ConnectionCurrent.BeginTransaction()
End Sub
Если вам нужна связь (connection) и не нужна поддержка транзакций, вы можете вызвать OpenConnection: 
Public Sub OpenConnection()
  ConnectionCurrent = New SqlConnection(sConnectionString)
  ConnectionCurrent.Open()
End Sub
Если пришло время выполнить транзакцию, вызывается следующая функция:
Public Sub CommitTransaction()
  TransactionCurrent.Commit()
End Sub
Если вам нужно откатить назад (roll back) транзакцию, вызыввется функция: 
Public Sub RollbackTransaction()
  TransactionCurrent.Rollback()
End Sub
Когда вы закончили работать с соединением (connection), вы должны закрыть его. Нижеследующая функция закрывает соединение и удаляет ссылку на объект соединения (connection object): 
Public Sub CloseConnection()
  If ConnectionCurrent Is Nothing Then
  Exit Sub
  End If
  If ConnectionCurrent.State = ConnectionState.Open Then
  ConnectionCurrent.Close()
  ConnectionCurrent = Nothing
  End If
End Sub

Рассмотрим теперь, что произойдет, если вам понадобится сделать вставку (insert) или обновление (update), которые являются частью транзакции. Именно для этой цели предназначена функция RunSQLNonQuery. Когда вы вызываете эту функцию, она создает новый инстанс класса SqlCommand, а затем устанавливает свойства соединения (Connection property) подобную текущему соединению (ConnectionCurrent), а свойства транзакции (Transaction property) такие как у текущей транзакции (TransactionCurrent). После этого выполняется инструкция SQL с помощью метода ExecuteNonQuery, который вызывает малые издержки, поскольку не возвращает никаких данных (см. Рисунок 2). 

Последняя функция в классе - это RunSQLScalar, которая выполняет инструкцию SQL и возвращает отдельный элемент информации (single piece of information). Эта функция полезна, если вам требуется взять один элемент данных, такой, например, как цена единицы товара (Unit Price). 

Если вы посмотрите на этот класс внимательнее, то вы увидите, что он stateful. Вы должны инстантиировать класс, открыть соединение (connection) с транзакцией, а затем выполнить код, который вы желаете сделать частью транзакции. После этого вы должны выполнить (commit) или откатить назад (roll back) эту транзакцию и, наконец, закрыть соединение. Все это не так сложно, поскольку вы инстантииируете класс, совершаете работу и закрываете соединение с помощью Windows-based или Web приложения. В моем примере приложение использует клиентский интерфейс на базе Windows и просто инстантиирует класс на время выполнения приложения. 

На Рисунке №3 показан простой интерфейс построенный на основе Windows forms. Вы выбираете Order из списка вверху, затем кликаете кнопки со стрелками и добавляете нужные строки с подробными данными (detail rows). На Рисунке 3 показана форма с двумя строками подробных данных. В данном примере имеются поля количество и дисконт (discount), которым для целей тестирования присвоены значения 1 и .15 соответственно.


После того, как вы ввели line items, кликните кнопку Insert - ADO.NET Trx для того, чтобы добавить новые элементы в таблицу Order Details (Подробные данные о заказе) вашей базы данных. 

Рассмотрим конструкцию формы. Orders list (cboOrders) и Products list (cboProducts) - это comboboxes, которые предоставляют список заказов и товаров. Вот мелочи, которые помогут вам сэкономить немного времени. Когда я строил форму, я спрятал все директивы ввода данных (data entry controls) и запустил каждую строку, как это требуется. Я присвоил свойству cboProducts.Visible значение False и попытался запустить его, когда запускал строку директив (row of controls). По какой-то причине каждый раз это порождает ошибку времени выполнения. Поэтому мне было интересно узнать, что произойдет, если поместить cboProducts в директиву Panel (Panel control). Я поместил Panel в форму (PnlProduct), поместил туда cboProducts, установил размер панели таким образом,чтобы он соответствовал cboProducts и задаю адрес (location) и видимость (visibility) для этой панели вместо того, чтобы задавать эти параметры для cboProducts. Это сработало хорошо.

Combobox контрол находится непосредственно под combobox контролом Orders- это cboProducts. CboProducts динамически помещается наверху первого textbox в строке (как, например, txtProductName_1), когда пользователь вводит данные в эту одну строку. 

Вы можете исследовать остальную часть интерфейса, выгрузив (downloading) эталонный код, находящийся по ссылке, приведенной в начале статьи. 

Рассмотрим код, который работает с транзакциями в клиенте (in the client). Когда пользователь кликает кнопку Injsert-ADO.NET Trx для того, чтобы вставить детали заказа (order details), выполняется событие cmdInsertADONet_Click. 

В первых трех строках события объявляются переменные: 
Dim sSQL As String
Dim sStatus As String = ""
Dim sOrderID As String
В этой точке вызывается метод CloseConnection (Закрыть соединение). Если соединения нет, ошибка не возникает, но если соединение имеется, то оно будет закрыто: 
oDB.CloseConnection()
Затем открывается соединение, и транзакция стартует: 
oDB.OpenConnectionTrans()
Следующие несколько строк кода довольно просты; они задают контролы, проверяют, было ли введено имя товара (product name), и получают текущий заказ: 
lblMessage.Text = ""
If txtProductName_1.Text <> "" Then
sOrderID = cboOrders.SelectedValue
If sOrderID = "" Then
lblMessage.Text = "You must select an order to add line items to"
Exit Sub
End If
Следующие несколько строк вставляют детали заказа в базу данных путем вызова функции InsertOrderDetail. Каждая из этих строчек вызывается в следующем формате, где значения из формы передаются в функцию: 
'Insert 1st order
sStatus = InsertOrderDetail(sOrderID, _
  txtProductID_1.Text, _
  txtUnitPrice_1.Text, _
  txtQuantity_1.Text, _
  txtDiscount_1.Text)
Единственные вещи, которые меняются для последующих вызовов, - это проверка sStatus с тем, чтобы удостовериться, что sStatus не содержит сообщений об ошибках, а директива (control) txtProductID не является пустой. Если эти критерии удовлетворены, осуществляется обращение к InsertOrderDetail: 
'Insert 2nd order
If sStatus = "" And txtProductID_2.Text <> "" Then
sStatus = InsertOrderDetail(sOrderID, _
  txtProductID_2.Text, _
  txtUnitPrice_2.Text, _
  txtQuantity_2.Text, _
  txtDiscount_2.Text)
End If
Я опустил вызовы для третьей и четвертой строк, т.к. они идентичны последней строки, за исключением того, что они ссылаются на разные директивы. 

После последнего обращения к InsertOrderDetail, вы можете очистить (clean up) транзакцию. Если sStatus ничего не содержит, возникает ошибка и транзакция откатывается назад (rolled back) путем вызова метода RollBackTransaction. В контроле lblMessage будут выданы сообщения об ошибке, как это можно видеть ниже: 
'Cleanup and rollback / commit
If sStatus <> "" Then
lblMessage.Text = _
  "Rolled back transaction due to error " _
  on row " _
  & " - " & sStatus
oDB.RollbackTransaction()
Exit Sub
End If
И, наконец, если ошибок не возникает, то для завершения транзакции вызывается метод CommitTransaction. LblMessage изменяется таким образом, чтобы отразить успешную запись в базу данных, и соединение закрывается: 
oDB.CommitTransaction()
lblMessage.Text = "Line items inserted ok"
oDB.CloseConnection()
End If
Функция InsertOrderDetail очень проста. Заголовок функции выглядит следующим образом: 
Function InsertOrderDetail(ByVal sOrderID As String, _
  ByVal sProductID As String, ByVal sUnitPrice As String, _
  ByVal sQuantity As String, ByVal sDiscount As String) _
  As String
Затем создаются две переменные 
Dim sSQL As String
Dim sInsertStatus As String
После этого создается инструкция SQL с использованием переданных параметров: 
sSQL = "INSERT INTO [Order Details] " _
  "(OrderID, ProductID, UnitPrice, Quantity," _ 
  "Discount) " 
sSQL &= "VALUES(" & sOrderID & "," & sProductID & "," _
  & sUnitPrice & ","
sSQL &= sQuantity & "," & sDiscount & ")"
Блок Try/Catch содержит вызов RunSQLNonQuery, которая действительно выполняет SQL. Обратите внимание, что генерируется исключение, если sInsertStatus устанавливается равным любому значению, отличному от пробела. Это дает возможность коду перехватывать в блоке Catch (Catch Block) все условия ошибки (error conditions). 
  Try
  sInsertStatus = oDB.RunSQLNonQuery(sSQL)
  If sInsertStatus <> "" Then
  Throw New System.Exception(sInsertStatus)
  End If
  Catch exc As Exception
  Return exc.Message
  End Try
End Function
Все очень просто. Вы можете видеть, что ADO.NET позволяет достаточно просто кодировать транзакции, если ваша база данных поддерживает их. 

Вторая часть вопроса месяца связана с производительностью (performance). Безусловно, поддержание соединения в открытом состоянии затрагивает с производительность. Как показано в данном примере, вы можете использовать ADO.NET для обработки транзакций и вам решать, сколько времени вы будете держать соединение открытым. ADO.NET также поддерживает пулинг соединений (connection pooling), поэтому открытие и закрытие соединений вызовет лишь незначительные издержки, если вы будете использовать одну и ту же строку соединения (connection string). 

Все вопросы и замечания по статье вы можете задать Куну по адресу: basics@microsoft.com. 

Ken Spencer works for 32X Tech (http://www.32X.com). 32X provides training, software development, and consulting services on Microsoft Technologies.

Категория: .NET | Добавил: virusik (04.07.2009)
Просмотров: 10847 | Комментарии: 72 | Рейтинг: 0.0/0 |
Всего комментариев: 481 2 3 4 5 »
48 3aplus63Unene  
0
[b][/b]

47 StephenUselt  
0
http://pst2017.onlinewebshop.net/gopro-3d-hero-cena.html

46 SvetaVeri  
0
интернет знакомства в челябинске
http://www.serialos.ru/forum/member.php?u=178672

однокласники интернет знакомства
http://traffpro.ru/user/Lusiuyre/

знакомства без регистрации бесплатно интернет
http://ucglossa.ru/forum/profile.php?mode=viewprofile&u=14957

интернет знакомства ростов
http://forum.orbitdownloader.com/profile.php?id=826692

форум интернет знакомств
http://zfvz.com/user/Lusiuyre/

www интернет знакомства
http://erage.eu/forum/profile.php?mode=viewprofile&u=475750

интернет знакомства фото телефон
http://zabudovnyky.kiev.ua/user/Lusiuyre/

интернет знакомства усолье
http://iridiumfax.com/BetaFaxForum/index.php?showuser=304422

интернет знакомства г самара
http://www.sky-tower.com/forum/profile.php?mode=viewprofile&u=122434

мамба интернет знакомства
http://www.bacne.info/forum/member.php?u=67838

интернет знакомства на 1 ночь

45 BiofArrefeLem  
0
Попробую объяснить в двух словах.
Каждый из нас не раз сталкивался с ситуацией,
когда обязаны заново инсталлировать Windows.
Уверен, что для всех это ситуация неприятна,потому-что:
- инсталляция занимает примерно 2 часа;
- впоследствии установки Windows
надо инсталлировать кучу
программ, которые используются на компьютере.
Так вот, чтобы избежать этих неприятных моментов
помогает создание образа системного диска.
Как мы будем создавать образ диска?
С помощью программы http://noutboom.ru - Acronics True Image.

44 SvetaVeri  
0
реальные интернет знакомства
http://e-naija.com/index.php?action=profile;u=15889

интернет знакомства в ишиме
http://storytonight.ru/index.php?action=profile;u=53371

бесплатные интернет знакомства в челябинске
http://team-tt.com/index.php?action=profile;u=1107

интернет знакомства интернетянки
http://httpwww.friskyradio.com/phpBB2/profile.php?mode=viewprofile&u=222978&sid=861e0c641395e3a9359bf62cd139daa1

сайт интернет знакомств регистрация бесплатно
http://toolszone.ro/forum3/member.php?action=profile&uid=32293

интернет знакомства химки
http://www.yellooow.com/vb/member.php?33-SocSets

интернет знакомства владикавказ
http://www.knignik.info/user/Zeraseus/

социальная сеть интернет знакомств
http://www.todoroff-wines.com/forum/profile.php?mode=viewprofile&u=153036

интернет знакомства свингеры
http://www.hookemreport.com/forum/member.php?3296-SocSets

интернет знакомства в воронеже бесплатно
http://www.house-of-hifi.com/forum/profile.php?mode=viewprofile&u=17968

интернет знакомства москва без регистрации

43 SvetaVeri  
0
знакомства в калининграде интернет
http://clients.redesignbox.com/android/wp-content/plugins/zingiri-forum/mybb/member.php?action=profile&uid=22730

интернет знакомства лесосибирск
http://hsaan-sch.com/vb/member.php?u=837

знакомства для интернета в серпухове
http://www.misrbaldy.com/vb/member.php?u=61084

интернет знакомства в амурской области
http://www.unitedcrawl.com/forum/index.php?action=profile;u=8657

интернет знакомства в краснодарском крае
http://fussballfreundetoeplitz.de/forum/member.php?action=profile&uid=74223

интернет знакомства в махачкале
http://war3.org.ua/member.php?u=13861

интернет знакомства бдсм
http://androidteam.ru/forum/member.php?u=58738

реальный сайт интернет знакомств
http://superddl.hu/forum/member.php?574469-SocSetRu

знакомства фото видео интернет
http://fun.ck.ua/user/SocSetRu/

интернет знакомства в астрахани
http://lesreloaders.free.fr/forum/profile.php?mode=viewprofile&u=8601

бесплатный сайт интернет знакомств

42 BiofArrefeLem  
0
Попробую объяснить в двух словах.
Каждый из нас не раз сталкивался с ситуацией,
когда приходится заново инсталлировать Windows.
Уверен, что для всех это ситуация неприятна тем,
что:
- инсталляция занимает примерно 2 часа;
- после установки Windows
должен инсталлировать кучу
программ, которые используются на компьютере.
Так вот, чтобы избежать этих неприятных моментов
помогает создание образа системного диска.
Как мы будем создавать образ диска?
С помощью программы http://noutboom.ru/note/index.php?SECTION_ID=2 - True Image.

41 PsydayPus  
0
Привет! Никто не работал с этими ребятами этими, ссылка ниже, можно им доверять? Хочу себе номер красивый, вот думаю чтобы не кинули:

40 eleplapletymn  
0
Сдам 3 квартирочку в жк http://opa.od.ua/tags/%E6%EA+%C1%E5%EB%FB%E9+%EF%E0%F0%F3%F1/ - белый парус
Одесса. неподалёку: клуб Аура, Черное море, крутые пентхаусы и Корона. Жилье с евроремонтом, фиолетовой гламурной мебелью и Одесской высококачественной бытовой техникой.

39 Bubexcume  
0
Корчась и извиваясь под губительными лучами лицемерия, погружаясь в пучину немого равнодушия, я сотрясаю воздух избитыми фразами, и тону в океане человеческой глупости.http://touch2game.ru - ..

1-10 11-20 21-30 31-40 41-48
Имя *:
Email *:
Код *:
вход на сайт
Категории раздела
C/С++ [24]
статьи о языке C/С++
Visual FoxPro [1]
информация о языке Visual FoxPro
.NET [24]
статьи о языке программирования .NET
ваши статьи [4]
здесь вы можете размещать сваи статьи
модинг [4]
статьи о модинге ПК
Поиск по сайту
наши опросы
каким браузерам вы пользуетесь
Всего ответов: 21
Мини-чат
помощь проекту
помоги проекту
ЯндексЯндекс. ДеньгиХочу такую же кнопку
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Каталог http://www.internetmir.ru Лучшие сайты интернета в каталоге Intenetmir
  • Delphi.int.ru - Сообщество программистов: общение, помощь, обмен опытом.
    реклама 88х31
    Каталог сайтов. Раскрутка. Хостинг. Каталог ссылок. Информационный портал - Старого.NET Шпоры, курсовые, пособия, рефераты, ВУЗы.
    Статистика
    webgari.com Рейтинг сайтов
    Раскрутка сайтов
    Яндекс цитирования
    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0