1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.transaction.memory;
18
19 import java.util.Map;
20 import java.util.concurrent.TimeUnit;
21
22 import junit.framework.JUnit4TestAdapter;
23 import static junit.framework.Assert.*;
24 import org.junit.Test;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.apache.commons.transaction.locking.LockException;
30 import org.apache.commons.transaction.locking.RWLockManager;
31 import org.apache.commons.transaction.util.RendezvousBarrier;
32
33 /**
34 * Tests for map wrapper.
35 */
36 public class PessimisticTxMapTest extends BasicTxMapTest {
37
38 private static final Log log = LogFactory.getLog(PessimisticTxMapTest.class.getName());
39
40 protected static final long TIMEOUT = Long.MAX_VALUE;
41
42 private static int deadlockCnt = 0;
43
44 public static junit.framework.Test suite() {
45 return new JUnit4TestAdapter(PessimisticTxMapTest.class);
46 }
47
48 public static void main(java.lang.String[] args) {
49 junit.textui.TestRunner.run(suite());
50 }
51
52 @Test
53 public void testMulti() {
54 log.info("Checking concurrent transaction features");
55
56 final PessimisticTxMap<String, String> txMap1 = new PessimisticTxMap<String, String>(
57 "txMap1");
58 final Map map1 = txMap1.getWrappedMap();
59
60 Thread thread1 = new Thread(new Runnable() {
61 public void run() {
62 txMap1.startTransaction(5, TimeUnit.MINUTES);
63 txMap1.put("key1", "value2");
64 synchronized (txMap1) {
65 txMap1.commitTransaction();
66 report("value2", (String) txMap1.get("key1"));
67 }
68 }
69 }, "Thread1");
70
71 txMap1.put("key1", "value1");
72
73 txMap1.startTransaction(5, TimeUnit.MINUTES);
74
75 report("value1", (String) txMap1.get("key1"));
76
77 thread1.start();
78
79
80
81 report("value1", (String) txMap1.get("key1"));
82
83 txMap1.put("key1", "value3");
84
85
86 synchronized (txMap1) {
87 txMap1.commitTransaction();
88 report("value3", (String) txMap1.get("key1"));
89 }
90 try {
91 thread1.join();
92 } catch (InterruptedException e) {
93
94 e.printStackTrace();
95 }
96 }
97
98 @Test
99 public void testConflict() {
100 log.info("Checking concurrent conflict resolvation features");
101
102 final RWLockManager<Object, Object> lm = new RWLockManager<Object, Object>();
103
104 lm.setAbsolutePrewaitTime(0);
105 final PessimisticTxMap<String, String> txMap1 = new PessimisticTxMap<String, String>(
106 "txMap1", lm);
107 final Map map1 = txMap1.getWrappedMap();
108
109 final RendezvousBarrier restart = new RendezvousBarrier("restart", TIMEOUT);
110
111 int conflictingRuns = 0;
112 int runs = 25;
113
114 for (int i = 0; i < runs; i++) {
115 System.out.println(i);
116
117 final RendezvousBarrier deadlockBarrier1 = new RendezvousBarrier("deadlock" + i,
118 TIMEOUT);
119
120 Thread thread1 = new Thread(new Runnable() {
121 public void run() {
122 txMap1.startTransaction(5, TimeUnit.MINUTES);
123 try {
124
125 txMap1.put("key2", "value2");
126 synchronized (deadlockBarrier1) {
127 deadlockBarrier1.meet();
128 deadlockBarrier1.reset();
129 }
130
131
132 txMap1.put("key1", "value2");
133 txMap1.commitTransaction();
134 } catch (LockException le) {
135 assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
136 deadlockCnt++;
137 txMap1.rollbackTransaction();
138 } catch (InterruptedException ie) {
139 } finally {
140 try {
141 synchronized (restart) {
142 restart.meet();
143 restart.reset();
144 }
145 } catch (InterruptedException ie) {
146 }
147
148 }
149 }
150 }, "Thread1");
151
152 thread1.start();
153
154 txMap1.startTransaction(5, TimeUnit.MINUTES);
155 try {
156
157 txMap1.get("key1");
158 synchronized (deadlockBarrier1) {
159 try {
160 deadlockBarrier1.meet();
161 } catch (InterruptedException e) {
162
163 e.printStackTrace();
164 }
165 deadlockBarrier1.reset();
166 }
167
168
169 txMap1.get("key2");
170 txMap1.commitTransaction();
171 } catch (LockException le) {
172 assertEquals(le.getCode(), LockException.Code.WOULD_DEADLOCK);
173 deadlockCnt++;
174 txMap1.rollbackTransaction();
175 } finally {
176 try {
177 synchronized (restart) {
178 restart.meet();
179 restart.reset();
180 }
181 } catch (InterruptedException ie) {
182 }
183
184 }
185
186
187
188 if (deadlockCnt != 1) {
189
190 conflictingRuns++;
191 }
192 assertTrue(deadlockCnt >= 1);
193 deadlockCnt = 0;
194
195 try {
196 thread1.join();
197 } catch (InterruptedException e) {
198
199 e.printStackTrace();
200 }
201
202 }
203 System.out.println();
204 System.out.println("Of the " + runs + " there were " + conflictingRuns
205 + " runs that rolled back both transactions!");
206 }
207
208 }