1 7 package org.jboss.test.cache.test.local; 8 9 import junit.framework.Test; 10 import junit.framework.TestCase; 11 import junit.framework.TestSuite; 12 import org.jboss.cache.CacheException; 13 import org.jboss.cache.PropertyConfigurator; 14 import org.jboss.cache.TreeCache; 15 import org.jboss.cache.lock.IsolationLevel; 16 import org.jboss.cache.lock.TimeoutException; 17 import org.jboss.cache.transaction.DummyTransactionManager; 18 import org.jboss.logging.Logger; 19 20 import javax.naming.Context ; 21 import javax.naming.InitialContext ; 22 import javax.transaction.UserTransaction ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.Properties ; 26 import java.util.Set ; 27 28 38 public class TxConcurrentBankUnitTestCase extends TestCase { 39 TreeCache cache; 40 private static Logger logger_ = Logger.getLogger(TxConcurrentBankUnitTestCase.class); 41 static Properties p = null; 42 String old_factory = null; 43 final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory"; 44 final String NODE = "/cachetest"; 45 final int ROLLBACK_CHANCE = 100; 46 47 static String customer[] = { "cu1", "cu2", "cu3" }; 48 static final int BOOKINGS = 1000; 49 static boolean _testFailedinThread = false; 50 51 public TxConcurrentBankUnitTestCase(String name) 52 { 53 super(name); 54 } 55 56 public void failMain() { 57 _testFailedinThread=true; 58 } 59 60 public void setUp() throws Exception 61 { 62 super.setUp(); 63 old_factory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY); 64 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY); 65 DummyTransactionManager.getInstance(); 66 if (p == null) { 67 p = new Properties (); 68 p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory"); 69 } 70 71 cache = new TreeCache(); 72 73 PropertyConfigurator config = new PropertyConfigurator(); 74 config.configure(cache, "META-INF/local-eviction-service.xml"); 75 76 cache.setIsolationLevel(IsolationLevel.SERIALIZABLE); 78 79 cache.createService(); 80 cache.startService(); 81 } 82 83 public void tearDown() throws Exception 84 { 85 super.tearDown(); 86 cache.stopService(); 87 DummyTransactionManager.destroy(); 89 if (old_factory != null) { 90 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory); 91 old_factory = null; 92 } 93 } 94 95 public void testConcurrentBooking() 96 { 97 Teller one, two; 98 try { 99 if(cache.get(NODE)==null) { 100 cache.put(NODE, "cu1", new Integer (1000)); 101 cache.put(NODE, "cu2", new Integer (1000)); 102 cache.put(NODE, "cu3", new Integer (1000)); 103 } 104 105 one = new Teller("one", cache); 106 two = new Teller("two", cache); 107 108 one.start(); 109 sleep(100); 110 two.start(); 111 one.join(); 112 two.join(); 113 114 log("lock info:\n" + cache.printLockInfo()+_testFailedinThread); 115 if(_testFailedinThread) fail(); 116 } catch (Exception e) { 117 e.printStackTrace(); 118 fail(e.toString()); 119 } finally { 120 128 } 129 } 130 131 void sleep(long timeout) 132 { 133 try { 134 Thread.sleep(timeout); 135 } catch (InterruptedException e) { 136 } 137 } 138 139 static void log(String msg) 140 { 141 logger_.info("-- [" + Thread.currentThread() + "]: " + msg); 143 } 144 145 public static Test suite() 146 { 147 return new TestSuite(TxConcurrentBankUnitTestCase.class); 148 } 149 150 public static void main(String [] args) 151 { 152 junit.textui.TestRunner.run(suite()); 153 } 154 155 class Teller extends Thread 156 { 157 TreeCache cache; 158 159 public Teller(String str, TreeCache cache) 160 { 161 super(str); 162 this.cache = cache; 163 } 164 165 public void run() 166 { 167 int count = customer.length; 168 UserTransaction tx = null; 169 try { 170 tx = (UserTransaction ) new InitialContext (p).lookup("UserTransaction"); 171 172 boolean again = false; 173 int src = 0; 174 int dst = 0; 175 int amo = 0; 176 int anz =0; 177 while(anz<BOOKINGS) { 178 if(!again) { 179 src = (int) (Math.random()*count); 180 dst = (int) (Math.random()*(count-1)); 181 amo =1+ (int) (Math.random()*20); 182 if(dst>=src) dst++; 183 } 184 185 tx.begin(); 186 HashMap accounts = getAccounts(); tx.commit(); 189 int sum = sumAccounts(accounts); 190 log(anz+": "+accounts+" Summe: "+sum); 191 if(sum!=3000) { 193 failMain(); 194 return; } 196 assertEquals("the sum of all accounts always has to be 3000", 3000, sum); 197 198 try { 199 tx.begin(); 200 deposit(customer[src], customer[dst], amo, tx); tx.commit(); again = false; 203 } 204 catch(TimeoutException timeout_ex) { 205 System.out.println("transaction is rolled back, will try again (ex=" + timeout_ex.getClass() + ")"); 206 tx.rollback(); 207 again = true; 208 } 209 catch(Throwable e) { 210 System.out.println("transaction is rolled back, will try again (ex=" + e.getMessage() + ")"); 211 tx.rollback(); 212 again = true; 213 } 214 anz++; 215 yield(); 216 } 217 } catch (Throwable t) { 218 t.printStackTrace(); 219 fail(t.toString()); 220 } 221 } 222 225 public void deposit(String from, String to, int amount, UserTransaction tx) throws Exception { 226 log("deposit("+from+", "+to+", "+amount+") called."); 227 int act; 228 act = ((Integer ) cache.get(NODE, from)).intValue(); 230 cache.put(NODE, from, new Integer (act-amount)); 231 log("deposit("+from+", "+to+", "+amount+") debited."); 232 233 if((int) (Math.random()*ROLLBACK_CHANCE) == 0) { 235 log("!!!manually set rollback ("+from+", "+to+", "+amount+")."); 236 tx.setRollbackOnly(); 237 throw new Exception ("Manually set rollback!"); 238 } 239 240 act = ((Integer ) cache.get(NODE, to)).intValue(); 242 cache.put(NODE, to, new Integer (act+amount)); 243 244 log("deposit("+from+", "+to+", "+amount+") finished."); 245 } 246 249 public HashMap getAccounts() throws CacheException { 250 log("getAccounts() called."); 251 HashMap result = new HashMap (); 252 try { 253 Set set = cache.getKeys(NODE); Iterator iter = set.iterator(); 255 while(iter.hasNext()) { 256 String name = (String ) iter.next(); 257 result.put(name, cache.get(NODE, name)); 258 } 259 return result; 260 } catch(CacheException ce) { 261 throw ce; 262 } 263 } 264 protected int sumAccounts(HashMap map) { 265 Iterator iter = map.values().iterator(); 266 int result = 0; 267 while(iter.hasNext()) { 268 result += ((Integer ) iter.next()).intValue(); 269 } 270 return result; 271 } 272 } 273 } 274 | Popular Tags |