我正在使用Parse.com
作为我应用的后端。来自Parse
的本地数据库似乎非常容易使用,因此我决定使用它。
我想创建一个包含Name
和PhoneNumber
的数据库。这很简单,只需制作new ParseObject
和pinInBackground()
即可。但是当我想删除重复的数字时,它会更复杂。首先,我需要搜索数据中是否已存在该数字,然后添加新数字(如果该数字不存在)。
执行此操作的方法是:
public void putPerson(final String name, final String phoneNumber, final boolean isFav) {
// Verify if there is any person with the same phone number
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseClass.PERSON_CLASS);
query.whereEqualTo(ParseKey.PERSON_PHONE_NUMBER_KEY, phoneNumber);
query.fromLocalDatastore();
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> personList,
ParseException e) {
if (e == null) {
if (personList.isEmpty()) {
// If there is not any person with the same phone number add person
ParseObject person = new ParseObject(ParseClass.PERSON_CLASS);
person.put(ParseKey.PERSON_NAME_KEY, name);
person.put(ParseKey.PERSON_PHONE_NUMBER_KEY, phoneNumber);
person.put(ParseKey.PERSON_FAVORITE_KEY, isFav);
person.pinInBackground();
} else {
Log.d(TAG, "Warning: " + "Person with the number " + phoneNumber + " already exists.");
}
} else {
Log.d(TAG, "Error: " + e.getMessage());
}
}
}
);
}
假设我想在数据库中添加3个人:
ParseLocalDataStore.getInstance().putPerson("Jack", "0741234567", false);
ParseLocalDataStore.getInstance().putPerson("John", "0747654321", false);
ParseLocalDataStore.getInstance().putPerson("Jack", "0741234567", false);
ParseLocalDataStore.getInstance().getPerson(); // Get all persons from database
请注意,第一个和第三个人具有相同的编号,因此第三个人不能添加到数据库中,但是......
此后的logcat
是:
12-26 15:37:55.424 16408-16408/D/MGParseLocalDataStore: Person:0741234567 was added.
12-26 15:37:55.424 16408-16408/D/MGParseLocalDataStore: Person:0747654321 was added.
12-26 15:37:55.484 16408-16408/D/MGParseLocalDataStore: Person:0741234567 was added.
12-26 15:37:55.494 16408-16408/D/MGParseLocalDataStore: Person database is empty
logcat
的最后一行来自向我展示数据库中所有人的方法:
public void getPerson() {
ParseQuery<ParseObject> query = ParseQuery.getQuery(ParseClass.PERSON_CLASS);
query.fromLocalDatastore();
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> personList,
ParseException e) {
if (e == null) {
if (personList.isEmpty()) {
Log.d(TAG, "Person database is empty");
} else {
for (ParseObject p : personList) {
Log.d(TAG, p.getString(ParseKey.PERSON_PHONE_NUMBER_KEY));
}
}
} else {
Log.d(TAG, "Error: " + e.getMessage());
}
}
});
}
所以有两个问题:
即使我检查了是否已存在,也会添加第三个数字。
向我显示所有人的方法告诉我,我的数据库中没有任何内容,即使在logcat中我可以看到它增加了3个人。
我认为问题是findInBackground()方法,它在另一个线程中完成所有工作。 有没有解决这个问题的方法?
答案 0 :(得分:1)
您的两个问题都是异步工作的结果。如果你两次调用putPerson
方法,它们将在不同的后台线程中同时运行,并且两个查找查询几乎可能几乎同时返回,并且肯定在第一次调用保存新人之前。
在您的示例中,getPerson
调用将在后台线程能够保存您的三个人之前返回。
您的问题与Parse或localDataStore无关,但这是一个典型的并发问题。您需要重新考虑如何在应用程序中处理并发性。
只要这只是一个本地问题,你就可以强加同步结构,即Bolts Framework(因为你正在使用Parse,它已经是你应用程序的一部分)。但是如果对addPerson
的调用是在多个地方完成的,那么您将始终面临这个问题,并且您必须找到其他解决方案或解决方法来处理并发问题。
并发是一个很重要的话题,你应该花些时间学习。