大型Android ORMLite数据库操作需要具有原子性

问题描述

我正在编写一个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 (将#修改为@)