1 8 package org.jboss.cache.transaction; 9 10 import junit.framework.Test; 11 import junit.framework.TestCase; 12 import junit.framework.TestSuite; 13 import org.apache.commons.logging.Log; 14 import org.apache.commons.logging.LogFactory; 15 import org.jboss.cache.CacheImpl; 16 import org.jboss.cache.config.Configuration; 17 import org.jboss.cache.factories.XmlConfigurationParser; 18 import org.jboss.cache.lock.IsolationLevel; 19 20 import javax.naming.Context ; 21 import javax.naming.InitialContext ; 22 import javax.naming.NamingException ; 23 import javax.transaction.UserTransaction ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.LinkedList ; 27 import java.util.List ; 28 import java.util.Properties ; 29 import java.util.Set ; 30 31 37 public class ConcurrentTransactionalTest extends TestCase 38 { 39 CacheImpl cache; 40 private Log logger_ = LogFactory.getLog(ConcurrentTransactionalTest.class); 41 static Throwable thread_ex = null; 42 final int NUM = 10000; 43 static Properties p = null; 44 String old_factory = null; 45 final String FACTORY = "org.jboss.cache.transaction.DummyContextFactory"; 46 47 public ConcurrentTransactionalTest(String name) 48 { 49 super(name); 50 } 51 52 public void setUp() throws Exception 53 { 54 super.setUp(); 55 old_factory = System.getProperty(Context.INITIAL_CONTEXT_FACTORY); 56 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY); 57 DummyTransactionManager.getInstance(); 58 if (p == null) 59 { 60 p = new Properties (); 61 p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory"); 62 } 63 } 64 65 private void createCache(IsolationLevel level) throws Exception 66 { 67 cache = new CacheImpl(); 68 cache.setConfiguration(new XmlConfigurationParser().parseFile("META-INF/local-service.xml")); 69 70 cache.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL); 71 cache.getConfiguration().setIsolationLevel(level); 72 cache.start(); 73 cache.put("/a/b/c", null); 74 } 75 76 private UserTransaction getTransaction() 77 { 78 UserTransaction tx = null; 79 try 80 { 81 tx = (UserTransaction ) new InitialContext (p).lookup("UserTransaction"); 82 } 83 catch (NamingException e) 84 { 85 e.printStackTrace(); 86 } 87 88 if (tx == null) 89 throw new RuntimeException ("Tx is null"); 90 91 return tx; 92 } 93 94 public void tearDown() throws Exception 95 { 96 super.tearDown(); 97 cache.stop(); 98 thread_ex = null; 99 DummyTransactionManager.destroy(); 100 if (old_factory != null) 101 { 102 System.setProperty(Context.INITIAL_CONTEXT_FACTORY, old_factory); 103 old_factory = null; 104 } 105 } 106 107 public void testConcurrentAccessWithRWLock() throws Throwable 108 { 109 createCache(IsolationLevel.REPEATABLE_READ); 110 work_(); 111 } 112 113 public void testConcurrentAccessWithExclusiveLock() throws Throwable 114 { 115 createCache(IsolationLevel.SERIALIZABLE); 116 work_(); 117 } 118 119 private void work_() throws Throwable 120 { 121 Updater one, two; 122 try 123 { 124 one = new Updater("Thread one"); 125 two = new Updater("Thread two"); 126 long current = System.currentTimeMillis(); 127 one.start(); 128 two.start(); 129 one.join(); 130 two.join(); 131 if (thread_ex != null) 132 throw thread_ex; 133 134 long now = System.currentTimeMillis(); 135 log("*** Time elapsed: " + (now - current)); 136 137 System.out.println("cache content: " + cache.toString()); 138 Set keys = cache.getKeys("/a/b/c"); 139 System.out.println("number of keys=" + keys.size()); 140 141 if (keys.size() != NUM) 142 { 143 scanForNullValues(keys); 144 145 try 146 { 147 System.out.println("size=" + keys.size()); 148 List l = new LinkedList (keys); 149 Collections.sort(l); 150 System.out.println("keys: " + l); 151 for (int i = 0; i < NUM; i++) 152 { 153 if (!l.contains(new Integer (i))) 154 System.out.println("missing: " + i); 155 } 156 157 LinkedList duplicates = new LinkedList (); 158 for (Iterator it = l.iterator(); it.hasNext();) 159 { 160 Integer integer = (Integer ) it.next(); 161 if (duplicates.contains(integer)) 162 { 163 System.out.println(integer + " is a duplicate"); 164 } 165 else 166 duplicates.add(integer); 167 } 168 } 169 catch (Exception e1) 170 { 171 e1.printStackTrace(); 172 } 173 } 174 175 assertEquals(NUM, keys.size()); 176 log("lock info:\n" + cache.printLockInfo()); 177 178 } 179 catch (Exception e) 180 { 181 e.printStackTrace(); 182 fail(e.toString()); 183 } 184 } 185 186 private void scanForNullValues(Set keys) 187 { 188 for (Iterator it = keys.iterator(); it.hasNext();) 189 { 190 Object o = it.next(); 191 if (o == null) 192 System.err.println("found a null value in keys"); 193 } 194 } 195 196 void log(String msg) 197 { 198 logger_.debug(" [" + Thread.currentThread() + "]: " + msg); 199 } 200 201 202 class Updater extends Thread 203 { 204 String val = null; 205 UserTransaction tx; 206 207 Updater(String name) 208 { 209 this.val = name; 210 } 211 212 public void run() 213 { 214 try 215 { 216 log("adding data"); 217 tx = getTransaction(); 218 for (int i = 0; i < NUM; i++) 219 { 220 log("adding data i=" + i); 221 tx.begin(); 222 cache.put("/a/b/c", i, val); 223 tx.commit(); 224 yield(); 225 } 226 } 227 catch (Throwable t) 228 { 229 t.printStackTrace(); 230 thread_ex = t; 231 } 232 } 233 } 234 235 public static Test suite() 236 { 237 return new TestSuite(ConcurrentTransactionalTest.class); 238 } 239 240 public static void main(String [] args) 241 { 242 junit.textui.TestRunner.run(suite()); 243 } 244 245 246 } 247 | Popular Tags |