Duplikaty rekordów

0

Witam,

mam taki problem: mam aplikację na androidzie która na bieżąco zakłada i robi update w tabelach w bazie SQLite.
Dodatkowa funkcja aplikacji to aktualizacja rekordów w tle. Co 30 sekund wywoływany jest nowy wątek, który aktualizuje pewne tebele.
Jest np. tabela test (_id int autoincrement unique, opis text, int id_Obce)
W tym wątku sprawdzam pole id_obce czy istnieje jeżeli nie to dodaję rekord, jeżeli tak to robię update.
Problem jest w tym, że pojawiają się dublety w stylu:

4,"opis7",111,
5,"opis1",129
6,"opis1",129
7,"opis1",130

jak sprawdzam ?

public boolean sprawdzCzyJestZam(long id) {
    boolean wynik = false;
    
    String rawQuery = "select count(*) from z where id_obce=" + String.valueOf(id);
    
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(rawQuery, null);

    if (cursor.getCount() == 0) {
        wynik = false;
                
    } else {
        cursor.moveToNext();
        int ile = cursor.getInt(0);
        if (ile==1) {
            wynik = true;
        } else {
            wynik = false;
        }
    }
    cursor.close();

    
    return wynik;
}

Korzystam (przy aktualizacji w tle) z połączenia do bazy tego głównego aplikacji. Macie może jakieś pomysły ?

0

Spróbuj moveToFirst() zamiast moveToNext() - tak przynajmniej podpowiada google.
select count(*) w Twoim przypadku zawsze zwróci wynik, więc sprawdzanie ilości rekordów IMHO jest zbędne. W przykładach na stackoverflow ludzie tak robią, może tak się powinno robić, ale na chłopski rozum jest to zbędne.
Nie używaj polskich nazw, po pierwsze nie robisz tego konsekwentnie, po drugie i tak mieszasz nazwy z angielskim.
Jeśli cursor zamkniesz w finally, kod będzie krótszy (nie jestem programistą java, więc mogłem zrobić błędy):

public boolean existsZ(long id) {
    String rawQuery = "select count(*) from z where id_obce=" + id.toString();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(rawQuery, null);
    try {
      if (cursor == null || cursor.getCount() == 0)
        return false;
        
      cursor.moveToFirst();
      return cursor.getInt(0) > 0;
    }
    finally {
      if (cursor != null)
        cursor.close();
    }
}

Serio masz tabelę o nazwie "z"? Do tego kolumny z polskimi nazwami?

0
ŁF napisał(a):

Serio masz tabelę o nazwie "z"? Do tego kolumny z polskimi nazwami?

nie, nie mam tabeli z. Podałem z głowy.
Spróbuję to zmienić.
Najgorsze to jest to, że zaobserwowałem to tylko przy akualizacji w wątku.

1

Nie wiem czy dobrze zrozumiałem, ale czy jest tu wiele wątków, które mogą równocześnie działać na tej tabeli?
Jeśli tak, to sprawdzanie selectem czy coś istnieje nie będzie wiarygodne, bo co z tego że wątek 1 widzi, że rekordu nr 10 nie ma, skoro wątek 2 chwilę później go dodał? I wtedy powstaje duplikat.

Tego typu sytuacje zwykle rozwiązywałem jakąś sekcją krytyczną, która pozwala tylko jednej sesji zapisać dany ID.
Np. może być to indeks unikalny na ID_OBCE - próbujesz "na pałę" wstawić rekord - jeśli zwracany jest wyjątek, to robisz UPDATE. Jeśli wyjątku nie było, no to wstawiłeś rekord.

0

Jest wiele wątków, ale każdy operuje na innej tablicy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1