Google Android - это несложно

Добро пожаловать на форум сайта startandroid.ru
Текущее время: 25 фев 2017, 13:10

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2, 3  След.
Автор Сообщение
СообщениеДобавлено: 01 дек 2011, 04:00 
Администратор
Аватар пользователя

Зарегистрирован: 07 янв 2012, 12:32
Сообщений: 1319
Благодарил (а): 0 раз.
Поблагодарили: 69 раз.
В этом уроке:

- используем транзакции при работе с БД

Click here to read this article!

_________________
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение


Последний раз редактировалось damager82 23 июн 2016, 22:18, всего редактировалось 11 раз(а).

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 10 май 2012, 09:09 

Зарегистрирован: 10 май 2012, 08:57
Сообщений: 1
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Спасибо за статью, пригодилась.
Вот еще в тему http://www.enterra.ru/blog/android_issues_with_sqlite/, тоже кое-что полезного взять можно.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 10 май 2012, 10:49 
Администратор
Аватар пользователя

Зарегистрирован: 07 янв 2012, 12:32
Сообщений: 1319
Благодарил (а): 0 раз.
Поблагодарили: 69 раз.
eugene78 писал(а):
Спасибо за статью, пригодилась.
Вот еще в тему http://www.enterra.ru/blog/android_issues_with_sqlite/, тоже кое-что полезного взять можно.

Спасибо, хороший материал! Добавлю ссылку в урок.

_________________
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 18 май 2012, 23:35 

Зарегистрирован: 07 май 2012, 01:32
Сообщений: 22
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Спасибо большое! Отличный урок.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 04 июн 2012, 11:44 

Зарегистрирован: 29 май 2012, 19:50
Сообщений: 13
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Цитата:
Это очень важно! Т.е. если вы открыли транзакцию, выполнили какие-либо действия и не закрыли транзакцию, то все операции будут считаться успешными и изменения будут внесены в БД. Поэтому закрытие транзакции необходимо выполнять и finally нам это гарантирует.


тут вроде надо
Цитата:
Это очень важно! Т.е. если вы открыли транзакцию, выполнили какие-либо действия и не закрыли транзакцию, то все операции будут считаться неуспешными и изменения не будут внесены в БД. Поэтому закрытие транзакции необходимо выполнять и finally нам это гарантирует.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 04 июн 2012, 12:20 
Администратор
Аватар пользователя

Зарегистрирован: 07 янв 2012, 12:32
Сообщений: 1319
Благодарил (а): 0 раз.
Поблагодарили: 69 раз.
alex6999 писал(а):
тут вроде надо
Цитата:
Это очень важно! Т.е. если вы открыли транзакцию, выполнили какие-либо действия и не закрыли транзакцию, то все операции будут считаться неуспешными и изменения не будут внесены в БД. Поэтому закрытие транзакции необходимо выполнять и finally нам это гарантирует.


Да, чето я фигню написал какую-то ... Спасибо за наблюдательность! Пофиксил

_________________
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 30 авг 2012, 16:46 
Аватар пользователя

Зарегистрирован: 30 авг 2012, 16:29
Сообщений: 2
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Цитата:
void myActions() {
db = dbh.getWritableDatabase();
delete(db, "mytable");
db.beginTransaction();
insert(db, "mytable", "val1");
db.setTransactionSuccessful();
insert(db, "mytable", "val2");
db.endTransaction();
insert(db, "mytable", "val3");
read(db, "mytable");
dbh.close();
}
Обратите внимание - несмотря на то, что val2 мы вставляли уже после подтверждения успешности транзакции, запись вставилась, вошла в эту транзакцию.



Получается, расположение метода setTransactionSuccessful() может быть любым между открытием и закрытием транзакции?


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 05 сен 2012, 10:37 
Администратор
Аватар пользователя

Зарегистрирован: 07 янв 2012, 12:32
Сообщений: 1319
Благодарил (а): 0 раз.
Поблагодарили: 69 раз.
d79 писал(а):
Получается, расположение метода setTransactionSuccessful() может быть любым между открытием и закрытием транзакции?

Получается так. Но, походу, это не приветствуется, т.к. в хелпе есть такой текст: "Do not do any more database work between calling this and calling endTransaction."

Пожалуй, надо мне отметить это в уроке.

_________________
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 03 фев 2013, 18:39 
Аватар пользователя

Зарегистрирован: 21 фев 2012, 20:11
Сообщений: 15
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Так же смогу сказать что, например, вставка записей (к примеру 1к) проходит быстрее в транзакции чем без.
Кстати актуально не только для SQLite


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 09:45 

Зарегистрирован: 31 май 2012, 00:06
Сообщений: 41
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Интересен такой момент: а что если делать SQLiteOpenHelper синглетоном?
Вроде работает нормально, и можно методы доступа синхронизировать. Вопрос только в том, надо ли закрывать SQLiteOpenHelper?
После каждого обращения делать закрытие накладно, но если никогда не закрывать (...close()), то что будет при убивании всех экземпляров активити, работающих с этим Хелпером?
Я так понимаю, что умная система должна сама убить (закрыть) Хелпер, как она закрывает например все in\outStream при выходе. Или же статический объект будет висеть вечно? Как вариант, можно запоминать время последнего обращения к хелперу, и если оно больше скажем 5 минут, то хелпер уничтожается. И при запросе воссаздается заново.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 09:54 
Аватар пользователя

Зарегистрирован: 26 июл 2012, 11:42
Сообщений: 712
Благодарил (а): 6 раз.
Поблагодарили: 18 раз.
Prospekt писал(а):
Интересен такой момент: а что если делать SQLiteOpenHelper синглетоном?
Вроде работает нормально, и можно методы доступа синхронизировать. Вопрос только в том, надо ли закрывать SQLiteOpenHelper?
После каждого обращения делать закрытие накладно, но если никогда не закрывать (...close()), то что будет при убивании всех экземпляров активити, работающих с этим Хелпером?
Я так понимаю, что умная система должна сама убить (закрыть) Хелпер, как она закрывает например все in\outStream при выходе. Или же статический объект будет висеть вечно? Как вариант, можно запоминать время последнего обращения к хелперу, и если оно больше скажем 5 минут, то хелпер уничтожается. И при запросе воссаздается заново.


Это будет велосипедом, для этого есть СontentProvider, который является синглтоном и все это берет на себя.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 10:21 

Зарегистрирован: 31 май 2012, 00:06
Сообщений: 41
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Гы,
У многих есть неравнодущее к некоторым аспектам программирования, некоторые видят все мировое зло в несоблюдении правил отступа, некоторые считают мастерское владение дебагером сутью программирования, а товарищ neoksi помещан на КонтентПровайдерах. Прямо через пост.

За ответ спасибо, но как-то это не то.
КП определенно хороши, но хочется вариант поминиатюрней. Хотя определенно большая часть правда в вашем посте содержится. Как я понимаю, Вы предлагаете все обращения к БД делать исключительно через КП?
И всеже если взяться за ответку и прикрутить 2 колеса. Ну хотя бы как вариант.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 10:27 
Аватар пользователя

Зарегистрирован: 26 июл 2012, 11:42
Сообщений: 712
Благодарил (а): 6 раз.
Поблагодарили: 18 раз.
damager82 писал(а):
d79 писал(а):
Получается, расположение метода setTransactionSuccessful() может быть любым между открытием и закрытием транзакции?

Получается так. Но, походу, это не приветствуется, т.к. в хелпе есть такой текст: "Do not do any more database work between calling this and calling endTransaction."

Пожалуй, надо мне отметить это в уроке.


Тут нужно учесть, что SQLite однопоточная БД и очередность запросов отдана на откуп программистам пишущим приложения.

1) Метод beginTransaction() отправляет в движок SQL команду скапливать запросы и не обрабатывать их;
2) Метод setTransactionSuccessful() отправляет в движок SQL команду, что блок запросов завершен;
3) Метод endTransaction() отправляет в движок SQL команду, распарсить и обработать запросы, которые были указанны в блоке транзаксации.

Если между 2 и 3 методом отправить ещё н-ное кол-во запросов, то они будут немедленно обработаны и запишутся в файл БД до обработки блока транзаксации. Но может возникнуть ситуация, когда этими запросами будет блокирован на запись файл БД, к которому затребует доступ блок транзаксации, что в свою очередь приведет к возникновению исключения доступа к файлу.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 10:38 

Зарегистрирован: 31 май 2012, 00:06
Сообщений: 41
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Я понимаю это, но ведь такие ограничения остаются и для ContentProvider-ов. Большинство примеров БД - это маленькие базы с одной таблицей, с мелкими методами getItem() getAll() insertItem() updateItem() deleteItem() и эти методы можно сделать синхронизированными виду малости исполняемого кода. (Не повлияет на скорость).
Согласитесь, что во множестве случаев легче иметь простенький вариант решения, а городить 3-4 таблицы, связанных между собой - это редкость. Пока встречал варианты только простых БД.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 10:40 
Аватар пользователя

Зарегистрирован: 26 июл 2012, 11:42
Сообщений: 712
Благодарил (а): 6 раз.
Поблагодарили: 18 раз.
Prospekt писал(а):
Гы,
У многих есть неравнодущее к некоторым аспектам программирования, некоторые видят все мировое зло в несоблюдении правил отступа, некоторые считают мастерское владение дебагером сутью программирования, а товарищ neoksi помещан на КонтентПровайдерах. Прямо через пост.

За ответ спасибо, но как-то это не то.
КП определенно хороши, но хочется вариант поминиатюрней. Хотя определенно большая часть правда в вашем посте содержится. Как я понимаю, Вы предлагаете все обращения к БД делать исключительно через КП?
И всеже если взяться за ответку и прикрутить 2 колеса. Ну хотя бы как вариант.


Prospekt
Программируя на другом языке и работая с SQLite, я уже сталкивался с проблемой разграничения доступа к однопоточной БД из разных потоков программы, и честно, это была ещё та головомойка. Тут же, разработчики Андроида предусмотрели механизм, который все делает за нас, да, для понимания начального он сложен. Плюс КП дает свои плюшки, к примеру автоматическое обновление данных в отображаемых элементах при изменении их в БД. Я призываю его использовать, так как в конечном итоге он упрощает жизнь и не надо будет искать, где же и почему вдруг возникло исключение, когда два потока приложения одновременно решили поработать с БД.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 11:01 

Зарегистрирован: 31 май 2012, 00:06
Сообщений: 41
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
По всей видимости есть необходимость в уроке "ContentProvider vs других вариантов" при работе с БД.
Какие плюсы он дает? Да комбинация ContentProvider и BroadCastResiever позволяют автоматически обнавлять данные в приложении и даже в GUI.

Цитата:
Согласитесь, что во множестве случаев легче иметь простенький вариант решения, а городить 3-4 таблицы, связанных между собой - это редкость. Пока встречал варианты только простых БД.

Возможно в сложных случаях это действительно головомойка, но в большинстве случаев БД в Android - это всего лишь прокладка между программой и жестким диском (или какой он там). Прогеров ломает самим считывать данные с диска и сохранять их там, поэтому используются минимум из функционала БД. Сложности возникают при полноценном юзаньи БД, как например программы на серверном оборудовании, а тут -то где можно черту ногу поломать в 3-х соснах. Я вроде не глупый, но представить ситуацию такую не могу для Android-а. Поделитесь плиз, для моего собственного развития.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 11:23 
Аватар пользователя

Зарегистрирован: 26 июл 2012, 11:42
Сообщений: 712
Благодарил (а): 6 раз.
Поблагодарили: 18 раз.
Prospekt
Если вы работаете с данными только из одной точки, к примеру из одной активити, то да, тут можно напрямую без КП обойтись. Но как только вы начинаете работать с данными из разных точек, активити, сервисы и ресиверы, то становится необходимым создание КП для централизации процесса и избегания проблем.

Возьмем абстрактный пример:
Есть программа будильник, которая хранит назначенные будильники в БД (это одна таблица) и ими можно управлять из активити. Но у нас программа с супер мега функцией, если послать на телефон смс в определенном формате, то она может активировать или дезактировать будильник на определенный день (реализуется через БроадкастРесивер).
И так наступает час Х, когда наш пользователь открыл активити и работает с настройкой будильника на субботу, а в тот же момент ему приходит супер смс от жены с требованием отключить будильник на субботу. Без КП, я даже не хочу гадать, какая ошибка может выскочить, при одновременном сохранении данных Пользователем и Ресивером, но с КП проблем не возникнет.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 07 мар 2013, 11:37 

Зарегистрирован: 31 май 2012, 00:06
Сообщений: 41
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
а разве synchronized не решит эту проблему, ну если синхронизировать запросы к данным?
Хотя конечно да, все равно придется БроадкастРесивер ставить, чтобы не было рассогласования между данными программы и бд.

Ладно, уговорили, может и стоит все запросы через КП делать. особых минусов, кроме объема кода нет + права на доступ выставлять.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 11 мар 2013, 19:19 

Зарегистрирован: 30 ноя 2012, 20:40
Сообщений: 13
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Вопрос не очень важный, просто по методике. Зачем в методе read проверять курсор на null? Разве может возникнуть такая ситуация? db.query все равно вернет Cursor, даже с нулем записей. А проверку мы и так сделаем в c.moveToFirst.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: 15 апр 2013, 15:29 

Зарегистрирован: 23 июл 2012, 19:31
Сообщений: 14
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
neoksi писал(а):
1) Метод beginTransaction() отправляет в движок SQL команду скапливать запросы и не обрабатывать их;
2) Метод setTransactionSuccessful() отправляет в движок SQL команду, что блок запросов завершен;
3) Метод endTransaction() отправляет в движок SQL команду, распарсить и обработать запросы, которые были указанны в блоке транзаксации.

Если между 2 и 3 методом отправить ещё н-ное кол-во запросов, то они будут немедленно обработаны и запишутся в файл БД до обработки блока транзаксации. Но может возникнуть ситуация, когда этими запросами будет блокирован на запись файл БД, к которому затребует доступ блок транзаксации, что в свою очередь приведет к возникновению исключения доступа к файлу.


Что-то не сходится, если они действительно будут немедленно обработаны и запишутся в файл БД до обработки блока транзаксации, то почему в примере
Код: [ Загрузить ] [ Скрыть ]
  1. void myActions() { 
  2.     db = dbh.getWritableDatabase(); 
  3.     delete(db, "mytable"); 
  4.     db.beginTransaction(); 
  5.     insert(db, "mytable", "val1"); 
  6.     db.setTransactionSuccessful(); 
  7.     insert(db, "mytable", "val2"); 
  8.     db.endTransaction(); 
  9.     insert(db, "mytable", "val3"); 
  10.     read(db, "mytable"); 
  11.     dbh.close(); 
  12.   } 

Вывод был таким:
Код: [ Загрузить ] [ Скрыть ]
  1. val1 
  2. val2 
  3. val3 

а не таким?
Код: [ Загрузить ] [ Скрыть ]
  1. val2 
  2. val1 
  3. val3 


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 41 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 4 часа


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB