From 9d1911dc65c597104314d59cc1d2fc6ca8778b3d Mon Sep 17 00:00:00 2001
From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de>
Date: Wed, 19 Jun 2013 14:36:30 +0200
Subject: [PATCH] Use ConcurrentHashMaps and Spring @Transactional

This should prevent concurrent ConcurrentModificationException after
application lock on undeploy.
---
 src/main/java/de/thm/arsnova/FeedbackStorage.java | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/main/java/de/thm/arsnova/FeedbackStorage.java b/src/main/java/de/thm/arsnova/FeedbackStorage.java
index 3ac11f55..7f62d24c 100644
--- a/src/main/java/de/thm/arsnova/FeedbackStorage.java
+++ b/src/main/java/de/thm/arsnova/FeedbackStorage.java
@@ -3,6 +3,10 @@ package de.thm.arsnova;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Transactional;
 
 import de.thm.arsnova.dao.IDatabaseDao;
 import de.thm.arsnova.entities.Feedback;
@@ -37,7 +41,7 @@ public class FeedbackStorage {
 	private IDatabaseDao dao;
 	
 	public FeedbackStorage(IDatabaseDao newDao) {
-		this.data = new HashMap<String, Map<String,FeedbackStorageObject>>();
+		this.data = new ConcurrentHashMap<String, Map<String,FeedbackStorageObject>>();
 		this.dao = newDao;
 	}
 
@@ -90,13 +94,14 @@ public class FeedbackStorage {
 		return null;
 	}
 
+	@Transactional(isolation = Isolation.READ_COMMITTED)
 	public boolean saveFeedback(String keyword, int value, User user) {
 		if (dao.getSession(keyword) == null) {
 			throw new NotFoundException();
 		}
 		
 		if (data.get(keyword) == null) {
-			data.put(keyword, new HashMap<String, FeedbackStorageObject>());
+			data.put(keyword, new ConcurrentHashMap<String, FeedbackStorageObject>());
 		}
 		
 		System.out.println(user.getUsername());
@@ -105,6 +110,7 @@ public class FeedbackStorage {
 		return true;
 	}
 
+	@Transactional(isolation = Isolation.READ_COMMITTED)
 	public void cleanFeedbackVotes(int cleanupFeedbackDelay) {
 		for (String keyword : data.keySet()) {
 			this.cleanSessionFeedbackVotes(keyword, cleanupFeedbackDelay);
-- 
GitLab