Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: .Net одна транзакция для всех адаптеров или таблиц Добавлено: 17.03.07 15:54  

Автор вопроса:  Neco | Web-сайт: neco.pisem.net | ICQ: 247906854 
Вопрос из двух частей.
Первое - удаляю данные из DataTable'ов. К примеру пять штук, нажимаю кнопку и имею код по типу:
tbl1.Rows[0].Delete();
tbl1.Rows[1].Delete();
tbl2.Rows[154].Delete();

и предположим, что третья строка не смогла удалится - хз почему - вылетел эксепшн, мы показали ошибку юзеру, всё в порядке, но первые две строки удалились, а третья нет - логическая целостность нарушена.
Как объеденить удаление одним действием, чтобы "либо всё, либо ничего"?
Данные между собой завязаны только логически - у меня, например, в одной таблице находятся слова на разных языках. Уникальность по двум полям - ID и LANG_ID. Если удалять, то данные на всех языках. Напрямую в базе, я бы сделал delete from man.dict where id=:id и не парился бы, а в таблицах приходится удалять построчно - и тут можно нарваться.
Я видел какие-то методы RejectChanges() у строк и таблиц, но они отменяют все изменения, а не только вот эти три последних. Надо как-то поставить отметку вначале этих действий, но как?

Второе - вносим изменения собственно в базу данных:

        private void Apply()
        {
            try
            {
                using (OracleConnection conn = new OracleConnection(pub.session.ConnectionString))
                {
                    //OracleConnection conn = new OracleConnection(pub.session.ConnectionString);
                    this.oRDER_RUN_TIME_TYPETableAdapter.Connection = conn;
                    this.oRDER_SQLTableAdapter.Connection = conn;
                    this.dICTTableAdapter.Connection = conn;
                    this.oRDER_PARAM_TYPETableAdapter.Connection = conn;
                    this.oRDER_RETURN_TYPETableAdapter.Connection = conn;

                    this.dICTTableAdapter.Update(this.xeDataSet.DICT);
                    this.oRDER_PARAM_TYPETableAdapter.Update(this.xeDataSet.ORDER_PARAM_TYPE);
                    this.oRDER_RETURN_TYPETableAdapter.Update(this.xeDataSet.ORDER_RETURN_TYPE);
                    this.oRDER_RUN_TIME_TYPETableAdapter.Update(this.xeDataSet.ORDER_RUN_TIME_TYPE);
                    this.oRDER_SQLTableAdapter.Update(this.xeDataSet.ORDER_SQL);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

И опять та же фигня - если что-то помешает посередине пути оновить данные, то мы получим нарушение целостности уже не в памяти, а в самой базе. Адаптеры можно объеденить одним коннектом, но не получается объеденить одной транзакцией. (((
Как быть?

Ответить

  Ответы Всего ответов: 8  

Номер ответа: 1
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #1 Добавлено: 17.03.07 23:08
using (SqlConnection connection =
            new SqlConnection(connectionString))
{
    SqlCommand command = connection.CreateCommand();
    SqlTransaction transaction = null;
    
    try
    {
        // BeginTransaction() Requires Open Connection
        connection.Open();
        
        transaction = connection.BeginTransaction();
        
        // Assign Transaction to Command
        command.Transaction = transaction;
        
        // Execute 1st Command
        command.CommandText = "Insert ...";
        command.ExecuteNonQuery();
        
        // Execute 2nd Command
        command.CommandText = "Update...";
        command.ExecuteNonQuery();
        
        transaction.Commit();
    }
    catch
    {
        transaction.Rollback();
        throw;
    }
    finally
    {
        connection.Close();
    }
}

Ответить

Номер ответа: 2
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #2 Добавлено: 17.03.07 23:10
transaction.Commit '// подверждаем транзакцию;
transaction.Rollback() '// откатываемся

Ответить

Номер ответа: 3
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #3
Добавлено: 17.03.07 23:14
пасиб конечно )
но я как бы про это знал... ))
мне надо:
1. Транзакцию в памяти. Чтобы таблицы содержали единовременную информацию.
2. Выполнить Update группой адаптеров одной транзакцией. А у адаптера нет свойства Transaction, как у команды.

Ответить

Номер ответа: 4
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #4
Добавлено: 17.03.07 23:22
и кстати, если позволишь заметить, не совсем правильный кусочек кода ты мне дал. )))
если коннект не пройдёт по причине неправильного пароля, к примеру, то этот блок вылетит с ошибкой Object instance not set - про транзакцию, которую он попытается откатить при том, что переменная ещё не будет заведена.

правильнее имхо делать так:
        private void Do()
        {
            try
            {
                using (OracleConnection conn = new OracleConnection(pub.session.ConnectionString))
                {
                    conn.Open();
                    using (OracleTransaction tran = conn.BeginTransaction())
                    {
                        using (OracleCommand cmd = new OracleCommand("", tran.Connection))
                        {
                            cmd.Transaction = tran;
                            try
                            {
                                // any code
                                tran.Commit();
                            }
                            catch (Exception ex)
                            {
                                tran.Rollback();
                                throw ex;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

Ответить

Номер ответа: 5
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #5
Добавлено: 19.03.07 18:54
Вообще DataAdapter может быть построен на основе DataCommand (в
конструктор ее передать, или в какое-нть свойство загнать)...

А поьзоваться визуальными компонентами для работы с данными - ИМХО
зло. Для чего-то сложнее Helo World лучше решения похитрее писать.

Ответить

Номер ответа: 6
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #6
Добавлено: 19.03.07 19:11
А поьзоваться визуальными компонентами для работы с данными

по ситуации. сейчас вот столкнулся с тем, что надо бы визуально - чтобы побыстрее писАлось. но если б не такие вот тонкости...
а насчёт DataCommand большое спасибо - попробую
наверно должно сработать

Ответить

Номер ответа: 7
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #7
Добавлено: 07.04.07 17:18
Народ!
Вопрос всё ещё открыт - идей ни у кого нет?

Вариант с созданием через команду в кострукторе не получился. Типизированый адаптер вообще не унаследован от простого адаптера - он просто внутри его как переменную содержит.

Сейчас решаю использовать вариант с тем, чтобы когда уже всё будет готово, объявить свойство CommandCollection публично ручками в подготовленном дизайнером коде. Тока при поправках датасета всё слетать будет...

Блевануть тянет, но не могу больше ничего придумать...

Ответить

Номер ответа: 8
Автор ответа:
 Павел



Администратор

ICQ: 326066673 

Вопросов: 368
Ответов: 5968
 Web-сайт: www.vbnet.ru
 Профиль | | #8
Добавлено: 07.04.07 18:24
Я бы рекомендовал переписать код с использованием нормальной архитектуры, и навсегда забыть про типизированные Dataset'ы, Table Adapter'ы и прочие поделки.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам