1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| package org.jboss.cache.interceptors; |
8 |
| |
9 |
| import org.jboss.cache.CacheException; |
10 |
| import org.jboss.cache.CacheSPI; |
11 |
| import org.jboss.cache.InvocationContext; |
12 |
| import org.jboss.cache.NodeSPI; |
13 |
| import org.jboss.cache.lock.NodeLock; |
14 |
| import org.jboss.cache.marshall.MethodCall; |
15 |
| import org.jboss.cache.marshall.MethodDeclarations; |
16 |
| import org.jboss.cache.optimistic.TransactionWorkspace; |
17 |
| import org.jboss.cache.optimistic.WorkspaceNode; |
18 |
| import org.jboss.cache.transaction.GlobalTransaction; |
19 |
| import org.jboss.cache.transaction.TransactionEntry; |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| public class OptimisticLockingInterceptor extends OptimisticInterceptor |
29 |
| { |
30 |
| private long lockAcquisitionTimeout; |
31 |
| |
32 |
842
| public void setCache(CacheSPI cache)
|
33 |
| { |
34 |
842
| super.setCache(cache);
|
35 |
842
| lockAcquisitionTimeout = cache.getConfiguration().getLockAcquisitionTimeout();
|
36 |
| } |
37 |
| |
38 |
2107988
| public Object invoke(InvocationContext ctx) throws Throwable
|
39 |
| { |
40 |
2107988
| MethodCall m = ctx.getMethodCall();
|
41 |
2107988
| Object retval = null;
|
42 |
| |
43 |
| |
44 |
| |
45 |
2107988
| switch (m.getMethodId())
|
46 |
| { |
47 |
1127
| case MethodDeclarations.optimisticPrepareMethod_id:
|
48 |
| |
49 |
1127
| GlobalTransaction gtx = getGlobalTransaction(ctx);
|
50 |
1127
| try
|
51 |
| { |
52 |
1127
| lockNodes(gtx);
|
53 |
| } |
54 |
| catch (Throwable e) |
55 |
| { |
56 |
0
| log.debug("Caught exception attempting to lock nodes ", e);
|
57 |
| |
58 |
0
| try
|
59 |
| { |
60 |
0
| unlock(gtx);
|
61 |
| } |
62 |
| catch (Throwable t) |
63 |
| { |
64 |
| |
65 |
0
| log.error("Failed to unlock nodes, after failing to lock nodes during a prepare! Locks are possibly in a very inconsistent state now!", t);
|
66 |
| } |
67 |
0
| throw e;
|
68 |
| } |
69 |
| |
70 |
| |
71 |
1127
| retval = super.invoke(ctx);
|
72 |
1098
| break;
|
73 |
1052380
| case MethodDeclarations.commitMethod_id:
|
74 |
51
| case MethodDeclarations.rollbackMethod_id:
|
75 |
| |
76 |
| |
77 |
1052431
| try
|
78 |
| { |
79 |
1052431
| retval = super.invoke(ctx);
|
80 |
| } |
81 |
| finally |
82 |
| { |
83 |
1052431
| try
|
84 |
| { |
85 |
1052431
| unlock(getGlobalTransaction(ctx));
|
86 |
| } |
87 |
| catch (Exception e) |
88 |
| { |
89 |
| |
90 |
0
| log.error("Failed to unlock nodes after a commit or rollback! Locks are possibly in a very inconsistent state now!", e);
|
91 |
| } |
92 |
| } |
93 |
1052431
| break;
|
94 |
0
| case MethodDeclarations.lockMethodLocal_id:
|
95 |
| |
96 |
0
| throw new CacheException("_lock() passed up the interceptor stack when Optimistic Locking is used. This is NOT supported.");
|
97 |
1054430
| default:
|
98 |
| |
99 |
1054430
| retval = super.invoke(ctx);
|
100 |
1054430
| break;
|
101 |
| } |
102 |
| |
103 |
2107959
| return retval;
|
104 |
| } |
105 |
| |
106 |
| |
107 |
| |
108 |
| |
109 |
| |
110 |
| |
111 |
1127
| private void lockNodes(GlobalTransaction gtx) throws InterruptedException
|
112 |
| { |
113 |
1127
| TransactionWorkspace<?, ?> workspace = getTransactionWorkspace(gtx);
|
114 |
0
| if (log.isDebugEnabled()) log.debug("Locking nodes in transaction workspace for GlobalTransaction " + gtx);
|
115 |
| |
116 |
1127
| for (WorkspaceNode workspaceNode : workspace.getNodes().values())
|
117 |
| { |
118 |
2863
| NodeSPI node = workspaceNode.getNode();
|
119 |
2863
| boolean acquired = node.getLock().acquire(gtx, lockAcquisitionTimeout, NodeLock.LockType.WRITE);
|
120 |
2863
| if (acquired)
|
121 |
| { |
122 |
0
| if (trace) log.trace("Acquired lock on node " + node.getFqn());
|
123 |
2863
| cache.getTransactionTable().addLock(gtx, node.getLock());
|
124 |
| } |
125 |
| else |
126 |
| { |
127 |
0
| throw new CacheException("Unable to acquire lock on node " + node.getFqn());
|
128 |
| } |
129 |
| |
130 |
| } |
131 |
| } |
132 |
| |
133 |
| |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
1052431
| private void unlock(GlobalTransaction gtx)
|
139 |
| { |
140 |
1052431
| TransactionEntry entry = txTable.get(gtx);
|
141 |
1052431
| entry.releaseAllLocksFIFO(gtx);
|
142 |
| } |
143 |
| |
144 |
| } |