1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| package org.jboss.cache.pojo.interceptors; |
9 |
| |
10 |
| import org.jboss.aop.joinpoint.Invocation; |
11 |
| import org.jboss.aop.joinpoint.MethodInvocation; |
12 |
| import org.jboss.cache.Cache; |
13 |
| import org.jboss.cache.CacheException; |
14 |
| import org.jboss.cache.CacheSPI; |
15 |
| import org.jboss.cache.Fqn; |
16 |
| import org.jboss.cache.lock.UpgradeException; |
17 |
| import org.jboss.cache.pojo.PojoCacheException; |
18 |
| import org.jboss.cache.pojo.impl.InternalConstant; |
19 |
| |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| public class PojoTxLockInterceptor extends AbstractInterceptor |
27 |
| { |
28 |
| public static final String LOCK_KEY = InternalConstant.POJOCACHE_KEY_PREFIX + "LOCK"; |
29 |
| |
30 |
| private final int RETRY = 5; |
31 |
| |
32 |
25119
| public Object invoke(Invocation in) throws Throwable
|
33 |
| { |
34 |
25119
| MethodInvocation invocation = (MethodInvocation) in;
|
35 |
25119
| try
|
36 |
| { |
37 |
25119
| handleLock(invocation);
|
38 |
25118
| return invocation.invokeNext();
|
39 |
| } |
40 |
| finally |
41 |
| { |
42 |
| |
43 |
| } |
44 |
| } |
45 |
| |
46 |
25119
| private void handleLock(MethodInvocation invocation) throws Throwable
|
47 |
| { |
48 |
25119
| Fqn id = (Fqn) invocation.getArguments()[0];
|
49 |
25119
| Cache<Object, Object> cache = getCache(invocation);
|
50 |
| |
51 |
25119
| Object owner = null;
|
52 |
25118
| if (!lockPojo(owner, id, cache))
|
53 |
| { |
54 |
0
| throw new PojoCacheException("PojoCache.removeObject(): Can't obtain the pojo lock under id: " + id);
|
55 |
| } |
56 |
| } |
57 |
| |
58 |
25119
| private boolean lockPojo(Object owner, Fqn id, Cache<Object, Object> cache) throws CacheException
|
59 |
| { |
60 |
25119
| if (log.isDebugEnabled())
|
61 |
| { |
62 |
0
| log.debug("lockPojo(): id:" + id + " Owner: " + owner);
|
63 |
| } |
64 |
| |
65 |
25119
| boolean isNeeded = true;
|
66 |
25119
| int retry = 0;
|
67 |
| |
68 |
| |
69 |
| |
70 |
25119
| Fqn realId = id;
|
71 |
25119
| if (id.isChildOrEquals(InternalConstant.JBOSS_INTERNAL) && id.size() > 2)
|
72 |
| { |
73 |
20740
| realId = id.getParent();
|
74 |
20740
| if (log.isDebugEnabled())
|
75 |
| { |
76 |
0
| log.debug("lockPojo(): will lock parent id instead:" + realId);
|
77 |
| } |
78 |
| } |
79 |
| |
80 |
25119
| while (isNeeded)
|
81 |
| { |
82 |
25119
| try
|
83 |
| { |
84 |
25119
| cache.put(realId, LOCK_KEY, "LOCK");
|
85 |
25118
| isNeeded = false;
|
86 |
| } |
87 |
| catch (UpgradeException upe) |
88 |
| { |
89 |
0
| log.warn("lockPojo(): can't upgrade the lock during lockPojo. Will re-try. id: " + realId
|
90 |
| + " retry times: " + retry); |
91 |
| |
92 |
| |
93 |
0
| if (retry++ > RETRY)
|
94 |
| { |
95 |
0
| return false;
|
96 |
| } |
97 |
| |
98 |
0
| try
|
99 |
| { |
100 |
0
| Thread.sleep(10);
|
101 |
| } |
102 |
| catch (InterruptedException e) |
103 |
| { |
104 |
| ; |
105 |
| } |
106 |
| } |
107 |
| } |
108 |
| |
109 |
25118
| return true;
|
110 |
| } |
111 |
| |
112 |
| } |