如何刷新其他用户Vaadin表而不会导致并发修改异常?

时间:2013-09-18 09:37:27

标签: multithreading user-interface web vaadin icepush

使用案例用户登录并打开了Vaadin表组件,显示约会状态。每行都有一个下拉(ComboBox)来更改状态(Scheduled,Arrived,Reviews)。现在,多个用户已在自己的浏览器中打开此表,并不断更改约会状态。这些更改应反映在所有已打开的表中,即如果用户A更改约会appt-1的状态,则会反映并刷新当前打开的所有表。

之前我们使用ICE-PUSH附加组件应用基于事件的刷新,即如果在PC-1上进行了更改(即应用程序实例a1),我从{{1}获取静态CopyOnWriteArrayList的其他Vaadin应用程序实例我通过该实例调用MainApplication函数。之后,我打电话给ICEPUSH,向所有用户推送新的更改。

loadTable

这样可以正常工作,但在某些情况下,当进行多次频繁更改时,会出现并发修改异常。所以,如果有人能帮助改善这一点吗?

我之后想到的解决方案是通过自己的应用实例在每1分钟内不是强有力地连续刷新表组件。这将查询数据库并使用更新的状态重新加载表容器。为此,我使用了Refresher附加组件但是它引发了一个异常,即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(); } } } ,因为有时用户也通过更改表中的组合状态来更改表组件,同时刷新表刷新表,这里引发并发修改异常。所以我想从用户的角度来冻结Table组件,这样用户就无法做任何事情,在后台可以轻松刷新表。

如果对于这个用例,你们有更好的解决方案,请告诉我。我很感激你。

使用Vaadin 6.8.12,java 1.7,apache Tomcat 7.42

1 个答案:

答案 0 :(得分:2)

Vaadin 6

您需要应用同步,因为您正在从另一个线程更改GUI(我认为使用Refresher或IcePush并不重要,我认为在这两种情况下您都将使用另一个线程)。在Application实例上进行同步。

请参阅Vaadin论坛上的this post

Vaadin 7

编辑:我建议您升级到Vaadin 7.1,并按照建议UI#accessUIhere上使用这种新方法。