Как обновить 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 # доступ, как рекомендуется здесь.