问题描述
我正在编写一个android应用程序,我需要一个大型的数据库事务来实现原子性,要么提交要么回滚跨越数据库中每个表的所有操作。
我找到了一种完美的方法TransactionManager.callInTransaction(callable)
。我创建了一个大的可调用的顺序操作,该方法返回的值是成功操作的期望值(Integer = 1),不会引发任何异常。
现在,我从android设备中提取数据库文件,并在编辑器中将其打开,但尚未提交任何更改。在事务中调试时,我能够检查可调用项末尾的表。这些表似乎是正确的,但是由于某些原因它们没有被写入硬盘。
注意:
如果我将其从事务管理器中取出,数据库将达到预期状态,并且代码可以正常工作。
问题可以在dao.callBatchTasks()
内调用callInTransaction
吗?它们都是原子的,但是如果callInTransaction
由于某种原因无法提交,则应该抛出异常。
Transaction Manager Documentation
代码
Callable<Integer> totalReload = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
ArrayList<Runnable> runnables = new ArrayList<>();
runnables.add(() -> repo.Manufacturers.deleteLargeList(idsFromDeletedStream(MANUFACTURER,deleted)));
runnables.add( () -> repo.PartType.deleteLargeList(idsFromDeletedStream(PART_TYPE,deleted)));
runnables.add( () -> repo.Part.deleteLargeList(idsFromDeletedStream(PART,deleted)));
runnables.add( () -> repo.CrossReference.deleteLargeList(idsFromDeletedStream(CROSS_REFERENCE,deleted)));
runnables.add( () -> repo.HomeText.deleteLargeList(idsFromDeletedStream(HOME_TEXT,deleted)));
runnables.add( () -> repo.AppHelp.deleteLargeList(idsFromDeletedStream(APP_HELP,deleted)));
runnables.add( () -> repo.CouplingStyles.deleteLargeList(idsFromDeletedStream(COUPLING_STYLE,deleted)));
runnables.add( () -> repo.Crimpers.deleteLargeList(idsFromDeletedStream(CRIMPER,deleted)));
runnables.add( () -> repo.CrimperReferences.deleteLargeList(idsFromDeletedStream(CRIMPER_REFERENCE,deleted)));
runnables.add( () -> repo.HoseSizes.deleteLargeList(idsFromDeletedStream(HOSE_SIZE,deleted)));
runnables.add( () -> repo.Note.deleteLargeList(idsFromDeletedStream(NOTE,deleted)));
runnables.add( () -> repo.HoseStyles.deleteLargeList(idsFromDeletedStream(HOSE_STYLE,deleted)));
runnables.add( () -> repo.Locations.deleteLargeList(idsFromDeletedStream(LOCATION,deleted)));
runnables.add( () -> repo.ReferenceMaterials.deleteLargeList(idsFromDeletedStream(REFERENCE_MATERIAL,deleted)));
runnables.add( () -> repo.Specifications.deleteLargeList(idsFromDeletedStream(SPECIFICATION,deleted)));
runnables.add( () -> repo.SpecImageReferences.deleteImagesForRefImage(idsFromDeletedStream(REFERENCE_MATERIAL,deleted)));
runnables.add( () -> repo.ExternalReference.deleteLargeList(idsFromDeletedStream(EXTERNAL_REFERENCE,deleted)));
Runnable manufacturerTask = () -> {
JsonArray manufacturerArr = response.getAsJsonArray("manufacturer");
Type manListType = new TypeToken<ArrayList<Manufacturer>>(){}.getType();
repo.Manufacturers.saveList(gson.fromJson(manufacturerArr,manListType));
};
runnables.add(manufacturerTask);
// PartType
Runnable partTypeTask = () -> {
JsonArray partTypeArr = response.getAsJsonArray("parttype");
Type partListType = new TypeToken<ArrayList<PartType>>() {
}.getType();
repo.PartType.saveList(gson.fromJson(partTypeArr,partListType));
};
runnables.add(partTypeTask);
// Part
Runnable partTask = () -> {
JsonArray partArr = response.getAsJsonArray("part");
Type partListType = new TypeToken<ArrayList<Part>>() {
}.getType();
List<Part> partList = gson.fromJson(partArr,partListType);
partList = java8.util.stream.StreamSupport.stream(partList)
.map(new Function<Part,Part>() {
@Override
public Part apply(Part part) {
part.setSearchable_part_number(Normalizer.normalize(part.getPartNumber().toLowerCase(),Normalizer.Form.NFD));
return part;
}
}).collect(toList());
repo.Part.saveList(partList);
};
runnables.add(partTask);
// Cross Reference crossreference - needs manufacturer and part
Runnable crossReferenceTask = () -> {
JsonArray crossReferenceArr = response.getAsJsonArray("crossreference");
Type crossReferenceListType = new TypeToken<ArrayList<Part>>(){}.getType();
List<CrossReference> crossReferenceArrayList = gson.fromJson(crossReferenceArr,crossReferenceListType);
crossReferenceArrayList = java8.util.stream.StreamSupport.stream(crossReferenceArrayList).map((crossReferenceObj) -> {
String partNumber = crossReferenceObj.getThird_party_part_number();
partNumber = partNumber.toLowerCase();
String normalized = Normalizer.normalize(partNumber,Normalizer.Form.NFD);
String nonAlphaNumericPartNumber = normalized.replaceAll("[^A-Za-z0-9]","");
crossReferenceObj.setSearchable_third_party_part_number(nonAlphaNumericPartNumber);
return crossReferenceObj;
}).collect(toList());
repo.CrossReference.saveList(crossReferenceArrayList);
};
runnables.add(crossReferenceTask);
Date date = new Date();
SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
final String sDateUpdated = simpleDateFormatter.format(date).toString();
// AppHelp apphelp
Runnable homeTextTask = () -> {
JsonArray homeTextArray = response.getAsJsonArray("hometext");
Type homeTextListType = new TypeToken<ArrayList<HomeText>>(){}.getType();
List<HomeText> homeTextArrayList = gson.fromJson(homeTextArray,homeTextListType);
homeTextArrayList = java8.util.stream.StreamSupport.stream(homeTextArrayList)
.map((homeText)->{
((HomeText) homeText).setUpdated(sDateUpdated);
return homeText;
}).collect(toList());
if(homeTextArrayList != null && homeTextArrayList.size() > 0) {
repo.HomeText.deleteAll();
repo.HomeText.saveList(homeTextArrayList);
}
};
runnables.add(homeTextTask);
// AppHelp apphelp
Runnable appHelpTask = () -> {
JsonArray appHelpArr = response.getAsJsonArray("apphelp");
Type appHelpListType = new TypeToken<ArrayList<AppHelp>>(){}.getType();
List<AppHelp> appHelps = gson.fromJson(appHelpArr,appHelpListType);
if(appHelps != null && appHelps.size()>0) {
repo.AppHelp.deleteAll();
repo.AppHelp.saveList(gson.fromJson(appHelpArr,appHelpListType));
}
};
runnables.add(appHelpTask);
Runnable couplingStyleTask = () -> {
JsonArray couplingStyleArr = response.getAsJsonArray("coupling_style");
Type couplingStyleListType = new TypeToken<ArrayList<CouplingStyle>>(){}.getType();
repo.CouplingStyles.saveList(gson.fromJson(couplingStyleArr,couplingStyleListType));
};
runnables.add(couplingStyleTask);
Runnable crimperTask = () -> {
JsonArray crimpArr = response.getAsJsonArray("crimper");
Type crimperListType = new TypeToken<ArrayList<Crimper>>(){}.getType();
repo.Crimpers.saveList(gson.fromJson(crimpArr,crimperListType));
};
runnables.add(crimperTask);
Runnable hoseSeriesTask = () -> {
JsonArray hoseSeriesArr = response.getAsJsonArray("hose_series");
Type hoseSeriesListType = new TypeToken<ArrayList<HoseSeries>>(){}.getType();
repo.HoseSeries.saveList(gson.fromJson(hoseSeriesArr,hoseSeriesListType));
};
runnables.add(hoseSeriesTask);
Runnable hoseSizeTask = () -> {
JsonArray hoseSizeArr = response.getAsJsonArray("hose_size");
Type hoseSizeListType = new TypeToken<ArrayList<HoseSize>>(){}.getType();
List<HoseSize> hoseSizes = gson.fromJson(hoseSizeArr,hoseSizeListType);
hoseSizes = java8.util.stream.StreamSupport.stream(hoseSizes)
.map((size) -> {
try{
size.setSizeValue(Utils.convertFrac(size.getSize()));
}catch (NumberFormatException e){
}finally {
return size;
}
}).collect(toList());
repo.HoseSizes.saveList(hoseSizes);
};
runnables.add(hoseSizeTask);
Runnable notesTask = () -> {
JsonArray noteArr = response.getAsJsonArray("note");
Type noteListType = new TypeToken<ArrayList<Note>>(){}.getType();
repo.Note.saveList((List<Note>) gson.fromJson(noteArr,noteListType));
};
runnables.add(notesTask);
Runnable hoseStyleTask = () -> {
JsonArray hoseStyleArr = response.getAsJsonArray("hose_style");
Type hoseStyleListType = new TypeToken<ArrayList<HoseStyle>>(){}.getType();
repo.HoseStyles.saveList((List<HoseStyle>) gson.fromJson(hoseStyleArr,hoseStyleListType));
};
runnables.add(hoseStyleTask);
Runnable locationTask = () -> {
JsonArray locationArr = response.getAsJsonArray("location");
Type locationListType = new TypeToken<ArrayList<StoreLocation>>(){}.getType();
repo.Locations.saveList((List<StoreLocation>) gson.fromJson(locationArr,locationListType));
};
runnables.add(locationTask);
Runnable referenceMatTask = () -> {
JsonArray referenceArr = response.getAsJsonArray("reference_material");
Type referenceListType = new TypeToken<ArrayList<ReferenceMaterial>>(){}.getType();
repo.ReferenceMaterials.saveList((List<ReferenceMaterial>) gson.fromJson(referenceArr,referenceListType));
};
runnables.add(referenceMatTask);
Runnable specTask = () -> {
JsonArray crimpSpecArr = response.getAsJsonArray("crimp_spec");
Type crimpSpecListType = new TypeToken<ArrayList<Specification>>(){}.getType();
List<Specification> specs = gson.fromJson(crimpSpecArr,crimpSpecListType);
//Pass to Mapper
CouplingStyle couplingStyle = (new CouplingStyle());
HoseStyle hoseStyle = new HoseStyle();
HoseSize hoseSize = new HoseSize();
Crimper crimper = new Crimper();
specs = java8.util.stream.StreamSupport.stream(specs)
.map(new Function<Specification,Specification>() {
@Override
public Specification apply(Specification specification) {
specification.setCouplingStyleObj(couplingStyle
.getCouplingStyleById(repo,specification.getCoupling_style()));
specification.setHoseStyle(hoseStyle
.getHoseStyleById(repo,specification.getHose_general()));
specification.setHoseSize(hoseSize.
getHoseSizeById(repo,specification.getHose_size()));
specification.setCrimperObj(crimper.getCrimperById(repo,specification.getCrimper()));
return specification;
}
}).collect(toList());
repo.Specifications.saveList(specs);
List<Integer> specIds = java8.util.stream.StreamSupport.stream(specs)
.map(new Function<Specification,Integer>() {
@Override
public Integer apply(Specification specification) {
return specification.getId();
}
}).collect(toList());
repo.SpecImageReferences.deleteImagesForSpec(specIds);
List<SpecImageReference> specImageReferences = java8.util.stream.StreamSupport.stream(specs)
.map(new Function<Specification,List<SpecImageReference>>() {
@Override
public List<SpecImageReference> apply(Specification specification) {
ArrayList<SpecImageReference> specImageReferences = new ArrayList<>();
for(Integer i: specification.getReferenceImage()){
SpecImageReference sIR = new SpecImageReference();
sIR.setSpecification_id(specification.getId());
sIR.setReferencematerial(i);
specImageReferences.add(sIR);
}
return specImageReferences;
}
}).flatMap(java8.util.stream.StreamSupport::stream).collect(toList());
repo.SpecImageReferences.saveList(specImageReferences);
};
//TODO External Reference externalreference - needs specification
Runnable externalRefTask = () -> {
JsonArray extRefArr = response.getAsJsonArray("externalreference");
Type extRefListType = new TypeToken<ArrayList<ExternalReference>>(){}.getType();
repo.ExternalReference.saveList((List<ExternalReference>) gson.fromJson(extRefArr,extRefListType));
};
int nReturn = 1;
try {
for (Runnable r : runnables) {
r.run();
}
specTask.run();
externalRefTask.run();
} catch (Exception e){
nReturn = 0;
throw e;
}finally {
return nReturn;
}
}
};
boolean isSuccess = true;
try {
TransactionManager transactionManager = new TransactionManager(repo.getDb().getConnectionSource());
Integer i = transactionManager.callInTransaction(totalReload);
return (isSuccess = 1 == i);
}catch (SQLException e){
e.printStackTrace();
Log.d("PARSEJSON","UNABLE TO COMMIT TRANSACTION");
return (isSuccess = false);
}finally {
long finishedParsingJson = System.currentTimeMillis();
if(isSuccess) {
Log.d("Time to Parse ",(finishedParsingJson - startedParsingJson) / 1000.0 + " seconds");
}else {
Log.d("Time to Parse ","Operation failed rolling back");
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)