简体   繁体   English

DAO和线程之间的同步

[英]DAO and Synchronization between threads

I'm developing a Javafx application, that synchronizes some data from two different databases. 我正在开发Javafx应用程序,该程序可以同步来自两个不同数据库的一些数据。 In the call method I get all the data and store it in an ArrayList . 在call方法中,我获取所有数据并将其存储在ArrayList Then I loop through the ArrayList and I try to get that same data from the second database. 然后,我遍历ArrayList ,然后尝试从第二个数据库中获取相同的数据。 If it exists I compare it for differences and if there are differences I update it. 如果存在,我比较它的差异,如果存在差异,我更新它。 Otherwise, if it dosen't exist, I insert it via a DAO object method. 否则,如果不存在,则通过DAO对象方法将其插入。 The problem is that sometimes the second database takes some time to provide the response so the process continues its execution and the new data will be compared with old data. 问题在于,有时第二个数据库需要一些时间来提供响应,因此该过程将继续执行,并将新数据与旧数据进行比较。 My question is, how can I stop the process until the data has all been fetched and then proceed to the synchronization logic? 我的问题是,如何才能停止该过程,直到所有数据都已被提取,然后继续进行同步逻辑?

@Override
protected Map call() throws Exception {
    Map<String, Integer> m = new HashMap();
    updateTitle( "getting the data ..." );
    int i, updated = 0, inserted = 0;
    // creating first database instance
    DAOFactory db1Dao = DAOFactory.getInstance( "db1" );
    //creating the first database dataObject instance
    Db1EmployerDAO empDb1Dao = db1Dao.getDAODb1Employer();
    // creating second database instance
    DAOFactory db2Dao = DAOFactory.getInstance( "db2" );
    //creating the second database dataObject instance
    Db2EmployeurDAO empDb2Dao = db2Dao.getDAODb2Employer();
    Employer emp;
    // getting all the object
    List< Employer > LEmpDb1 = empDb1Dao.getAll();
    updateTitle( "Data proccessing ..." );
    //for each data in the list
    for( i = 1; i <= LEmpDb1.size(); i++ ){
        if( isCancelled() )
            break;
        updateMessage( "Processing employer : "+ LEmpDb1.get( i-1 ).getNemploy() +" "+ LEmpDb1.get( i-1 ).getRaison() );

    //trying to get the object from the second database which the
    //process sometimes pass befor the result is getting which is my problem
        emp = empDb2Dao.getEmployerByNo( LEmpDb1.get( i-1 ).getNemploy() );
        if( emp != null){
            if( !LEmpDb1.get( i-1 ).equals( emp ) )
                if( empDb2Dao.update( LEmpDb1.get( i-1 ) ) ){
                    updated++;
                    LOG.log( "MAJ employeur : "+  LEmpDb1.get( i ).getNemploy()+" => "+LEmpDb1.get( i ).getDifferences( emp ) );
                }
        } else {
            if( empDb2Dao.insert( LEmpDb1.get( i-1 ) ) )
                inserted++;
        }
        updateProgress( i, LEmpDb1.size() );
    }
    m.put( "upd", updated );
    m.put( "ins", inserted );
    m.put( "all", LEmpDb1.size() );
    return m;
}

The getEmployerByNo method getEmployerByNo方法

public synchronized Employer getEmployerByNo( String no_emp ) throws DAOException {
    Employeur emp = null;
    Connection con = null;
    PreparedStatement stm = null;
    ResultSet res = null;
    try{
        con = dao.getConnection();
        stm = preparedRequestInitialisation( con, GET_BY_NO_SQL, no_emp );
        res = stm.executeQuery();
        if( res.next() ){
        //map is a function that map the database resultset data with the object properties
            emp = map( res );
            LOG.info( "getting the employer : "+ no_emp );
        }
    } catch( SQLException e ){
        throw new DAOException( e.getLocalizedMessage() );
    } finally{
        silentClose( res, stm, con );
    }
    return emp;
}

Look into using an ExecutorService and Future.get() as needed to wait for completion. Future.get()根据需要使用ExecutorServiceFuture.get()以等待完成。 See the documentation here and here . 请在此处此处查看文档。 Here is a more-or-less complete example: 这是一个或多或少的完整示例:

public class Application implements Runnable {

    private final ExecutorService pool = Executors.newCachedThreadPool();

    public void run() {
        Dao firstDao = new DaoImpl();
        Dao secondDao = new AnotherDaoImpl();

        FetchAllTask fetchAll = new FetchAllTask(firstDao);
        Future<?> fetchAllFuture = pool.submit(fetchAll);
        try {
            fetchAllFuture.get();
        } catch (Exception e) {
            // TODO handle
            System.out.println("An exception occurred!");
            e.printStackTrace();
        }
        ConcurrentSkipListSet<AnObject> items = fetchAll.getItems();
        Iterator<AnObject> it = items.iterator();
        while (it.hasNext()) {
            // insert your cancellation logic here
            // ...
            AnObject daoObj = it.next();
            FetchOneTask fetchOne = new FetchOneTask(secondDao, daoObj.getId());
            Future<?> fetchOneFuture = pool.submit(fetchOne);
            try {
                fetchOneFuture.get();
                AnObject anotherDaoObj = fetchOne.getAnObject();
                if (anotherDaoObj == null) {
                    // the object retrievied by the first dao (first datasource)
                    // is not in the second; it needs to be inserted into the second
                    System.out.println(String.format("Inserting %s", daoObj));
                    secondDao.insert(daoObj);
                } else {
                    System.out.println(String.format("Updating %s to %s", anotherDaoObj, daoObj));
                    secondDao.update(daoObj);
                }
            } catch (Exception e) {
                System.out.println("An exception occurred!");
                e.printStackTrace();
            }
        }

        Set<AnObject> itemsInSecondDb = secondDao.fetchAll();
        for (AnObject o : itemsInSecondDb) {
            System.out.println(o);
        }

        pool.shutdown();
    }

    // ... invoke the app thread from somewhere else

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM