Russian Qt Forum
Сентябрь 30, 2024, 22:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: SQLite и «вложенная транзакция»  (Прочитано 5931 раз)
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« : Июнь 07, 2011, 11:26 »

Суть:
1) Есть БД.
2) Есть программа, её использующая (на чтение) и есть редактор.

Логика работы редактора примерно такая:
а) создаём копию БД
б) редактируем (со своими транзакциями и т.п.), в это время основная программа должна видеть старую версию БД.
в) после редактирования либо принимаем изменения (заменяем БД, на её копию), либо отклоняем все изменения (просто забываем о редактированной копии).

Собственно вопрос - как это правильно сделать?

Вижу два варианта:
1) Скопировать файл БД и редактировать его.
минусы:
- если переходить на серверную БД видимо придётся всё переписывать;
- непонятно что будет, если при обратной замене БД основная программа к ней обратится.

2) Скопировать внутри БД все таблицы TableName1, TableName2, ... TableNameN в их копии edit_TableName1, edit_TableName2, ... edit_TableNameN и редактировать их.
минусы:
- при изменении структуры БД надо следить за тем, чтобы структуры TableNameX и edit_TableNameX оставались одинаковыми.

Может есть ещё какие-нибудь предложения по организации этого безобразия?
Записан
Igore
Гость
« Ответ #1 : Июнь 07, 2011, 12:03 »

QSqlTableModel::OnManualSubmit
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #2 : Июнь 07, 2011, 12:14 »

QSqlTableModel::OnManualSubmit
1) В программе в виде таблицы данные не представляются.
2) Хотелось бы использовать бизнес логику для проверки вводимых значений (тригерры в БД) во время редактирования, а не только по окончанию.
Записан
Igore
Гость
« Ответ #3 : Июнь 07, 2011, 13:25 »

Раз идет речь о копировании файла БД, то предположу что это SQLite, по своему опыту могу сказать что для многопользовательского режима она почти не предназначена, поэтому либо вариан 1 с копированием и последующей заменой. Либо через QSqlTableModel и нормальной БД.

Данные из модели можно представлять как угодно, таблица, список, свои виджеты. Данные можно проверять и на стороне клиента, в любом случае можно сделать Transaction.Start, а при не нужности изменений Rollback.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #4 : Июнь 07, 2011, 13:55 »

Раз идет речь о копировании файла БД, то предположу что это SQLite
Даже не знаю, что натолкнуло вас на таку мысль…
Может быть название темы? Веселый

по своему опыту могу сказать что для многопользовательского режима она почти не предназначена
Большую часть времени клиент будет 1. Во время редактирования - 2, причём один только читает. SQLite вполне с этим справится.

Данные можно проверять и на стороне клиента
Можно, более того они будут там проверяться, но всегда есть шанс, что что-то неодинаково проверишь в программе и триггерах, а в итоге все (потенциально долгие изменения) из-за этого не закомитятся, что ни есть хорошо.

в любом случае можно сделать Transaction.Start, а при не нужности изменений Rollback
Транзакция делается на каждом этапе редактирования. Единую транзакцию делать на все изменения не вариант, так как если у нас при редактировании не удалось 15-ое изменение, это значит, что должно откатиться оно, а не все 15 с самого начала процесса редактирования.
Логически редактирование представляется так:
Код
SQL
Transaction.Begin
 
   SubTransaction1.Begin
        Change1
   SubTransaction1.Commit
 
   SubTransaction2.Begin
        Change2
   SubTransaction2.Commit
 
   SubTransaction3.Begin
        Change3
   SubTransaction3.Commit
 
   …
 
   SubTransactionN.Begin
        ChangeN
   SubTransactionN.Commit
 
Transaction.Commit
Но вложенные транзакции поддерживают далеко не все БД.
Записан
ddrtn
Гость
« Ответ #5 : Июнь 09, 2011, 13:49 »

Как вариант - create temp table.  создать копию таблицы. temp таблицы удаляются при отключения от БД.
но лучше покурить savepoints - это такой хороший механизм именованных транзакций в sqlite. при отмене можно откатываться к одной из нескольких именованных точек. коммитить их также можно по очереди
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #6 : Июнь 09, 2011, 14:38 »

но лучше покурить savepoints - это такой хороший механизм именованных транзакций в sqlite. при отмене можно откатываться к одной из нескольких именованных точек. коммитить их также можно по очереди
Почитал, попробовал. Оно конечно хорошо и почти то что нужно, но увы, если происходит ошибка, то откатываются все изменения до самого первого сейвпоинта, а не только внутренний, так что придётся всё же копировать таблицы. Грустный
Но за помощь спасибо.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.082 секунд. Запросов: 22.