Как обновить Vaadin Table других пользователей, не вызывая исключения параллельной модификации?

Вариант использования: пользователь вошел в систему и открылся компонент Vaadin Table, отображающий статусы встреч. В каждой строке есть выпадающий список (ComboBox) для изменения статуса (Запланировано, Прибыл, Проверено). Теперь несколько пользователей открыли эту таблицу в своих браузерах и постоянно вносят изменения в статус встречи. Эти изменения должны быть отражены во всех открытых таблицах, т. Е. Если пользователь А изменяет статус встречи appt-1, он отражает и обновляет все открытые таблицы.

Ранее мы применяли обновление на основе событий с помощью надстройки ICE-PUSH, т. Е. Если изменения сделаны на ПК-1 (т. Е. Экземпляр приложения a1), я получаю другие экземпляры приложения Vaadin из статического CopyOnWriteArrayList от MainApplication класс и в этом случае я называю loadTable функция. после этого я звоню в ICEPUSH, чтобы протолкнуть новые изменения всем пользователям.

public class MainApplication extends Application {
    public static CopyOnWriteArrayList<MainMedMaxApplication> appList=new CopyOnWriteArrayList<MainMedMaxApplication>();

    @Override
    public void init() {
        setMainWindow(new Window("APPointment Dashboard"));
        getMainWindow().setContent(mainLayout);
        setMainComponent(getCustomTable());
        //Custome Table make table . it also register listeners over table.
        //loadTable will load the table. 
        loadTable()
        appList.add(this);  
    } 
}

public void loadTabl(String date) {
    //this will reload the table component By Querying database
}
private void registerlistener() {
    table.addListeners()
        {
        //do any change to table in this instance and save it to db then call ICE push so it can referesh all app instances by getting from applist.
        synchronizePortlets();
        }
}
public void synchronizePortlets() {
    // TODO Auto-generated method stub
    Iterator<MainApplication>itM = appList.iterator();
    while(itM.hasNext()) {
        MainApplication app = itM.next();
        app.loadTabl();
        app.getPusher().push();
    }
}
}

Это работает нормально, но в некоторых условиях, когда ко многим частым изменениям вносится исключение Concurrent Modification Exception. так что если кто-то может помочь улучшить это?

Решение, о котором я думаю после этого, состоит в том, чтобы обновлять компонент таблицы не принудительно, а достаточно непрерывно в каждом 1-м экземпляре его собственными экземплярами приложения. Это запросит базу данных и перезагрузит контейнер таблицы с обновленными статусами. Для этого я использую дополнение Refresher, но оно вызывает исключение, т.е. ConcurrentModificationExceptionпотому что иногда пользователь также изменяет компонент таблицы, изменяя комбо-статусы в таблице, в то время как обновление обновляет таблицу, и здесь возникает параллельное исключение модификации. Так что я думаю о замораживании компонента Table с точки зрения пользователя, чтобы пользователь ничего не мог сделать, а в фоновом режиме можно легко обновить таблицу.

Если для этого случая использования у вас есть лучшее решение, пожалуйста, скажите мне. Я благодарен вам.

Использование Vaadin 6.8.12, Java 1.7, Apache Tomcat 7.42

1 ответ

Ваадин 6

Вам необходимо применить синхронизацию, поскольку вы вносите изменения в графический интерфейс из другого потока (и я думаю, что не имеет значения, используется ли Refresher или IcePush, я думаю, что в обоих случаях вы будете использовать другой поток). Синхронизировать на Application пример.

Смотрите этот пост на форуме Vaadin.

Ваадин 7

РЕДАКТИРОВАТЬ: я призываю вас перейти на Vaadin 7.1 и использовать этот новый метод на UI: UI # доступ, как рекомендуется здесь.

Другие вопросы по тегам