1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.transaction.interceptor;
18
19 import java.io.Serializable;
20 import java.util.Properties;
21
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.junit.rules.ExpectedException;
25
26 import org.springframework.aop.framework.ProxyFactory;
27 import org.springframework.beans.factory.BeanFactory;
28 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
29 import org.springframework.transaction.PlatformTransactionManager;
30 import org.springframework.transaction.TransactionDefinition;
31 import org.springframework.transaction.TransactionException;
32 import org.springframework.transaction.TransactionStatus;
33 import org.springframework.util.SerializationTestUtils;
34
35 import static org.junit.Assert.*;
36 import static org.mockito.BDDMockito.*;
37 import static org.mockito.Mockito.mock;
38 import static org.mockito.Mockito.times;
39 import static org.mockito.Mockito.verify;
40
41
42
43
44
45
46
47 public class TransactionInterceptorTests extends AbstractTransactionAspectTests {
48
49 @Rule
50 public final ExpectedException thrown = ExpectedException.none();
51
52 @Override
53 protected Object advised(Object target, PlatformTransactionManager ptm, TransactionAttributeSource[] tas) throws Exception {
54 TransactionInterceptor ti = new TransactionInterceptor();
55 ti.setTransactionManager(ptm);
56 ti.setTransactionAttributeSources(tas);
57
58 ProxyFactory pf = new ProxyFactory(target);
59 pf.addAdvice(0, ti);
60 return pf.getProxy();
61 }
62
63
64
65
66
67
68 @Override
69 protected Object advised(Object target, PlatformTransactionManager ptm, TransactionAttributeSource tas) {
70 TransactionInterceptor ti = new TransactionInterceptor();
71 ti.setTransactionManager(ptm);
72 assertEquals(ptm, ti.getTransactionManager());
73 ti.setTransactionAttributeSource(tas);
74 assertEquals(tas, ti.getTransactionAttributeSource());
75
76 ProxyFactory pf = new ProxyFactory(target);
77 pf.addAdvice(0, ti);
78 return pf.getProxy();
79 }
80
81
82
83
84
85 @Test
86 public void serializableWithAttributeProperties() throws Exception {
87 TransactionInterceptor ti = new TransactionInterceptor();
88 Properties props = new Properties();
89 props.setProperty("methodName", "PROPAGATION_REQUIRED");
90 ti.setTransactionAttributes(props);
91 PlatformTransactionManager ptm = new SerializableTransactionManager();
92 ti.setTransactionManager(ptm);
93 ti = (TransactionInterceptor) SerializationTestUtils.serializeAndDeserialize(ti);
94
95
96 assertNotNull(ti.logger);
97 assertTrue(ti.getTransactionManager() instanceof SerializableTransactionManager);
98 assertNotNull(ti.getTransactionAttributeSource());
99 }
100
101 @Test
102 public void serializableWithCompositeSource() throws Exception {
103 NameMatchTransactionAttributeSource tas1 = new NameMatchTransactionAttributeSource();
104 Properties props = new Properties();
105 props.setProperty("methodName", "PROPAGATION_REQUIRED");
106 tas1.setProperties(props);
107
108 NameMatchTransactionAttributeSource tas2 = new NameMatchTransactionAttributeSource();
109 props = new Properties();
110 props.setProperty("otherMethodName", "PROPAGATION_REQUIRES_NEW");
111 tas2.setProperties(props);
112
113 TransactionInterceptor ti = new TransactionInterceptor();
114 ti.setTransactionAttributeSources(new TransactionAttributeSource[] {tas1, tas2});
115 PlatformTransactionManager ptm = new SerializableTransactionManager();
116 ti.setTransactionManager(ptm);
117 ti = (TransactionInterceptor) SerializationTestUtils.serializeAndDeserialize(ti);
118
119 assertTrue(ti.getTransactionManager() instanceof SerializableTransactionManager);
120 assertTrue(ti.getTransactionAttributeSource() instanceof CompositeTransactionAttributeSource);
121 CompositeTransactionAttributeSource ctas = (CompositeTransactionAttributeSource) ti.getTransactionAttributeSource();
122 assertTrue(ctas.getTransactionAttributeSources()[0] instanceof NameMatchTransactionAttributeSource);
123 assertTrue(ctas.getTransactionAttributeSources()[1] instanceof NameMatchTransactionAttributeSource);
124 }
125
126 @Test
127 public void determineTransactionManagerWithNoBeanFactory() {
128 PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
129 TransactionInterceptor ti = transactionInterceptorWithTransactionManager(transactionManager, null);
130
131 assertSame(transactionManager, ti.determineTransactionManager(new DefaultTransactionAttribute()));
132 }
133
134 @Test
135 public void determineTransactionManagerWithNoBeanFactoryAndNoTransactionAttribute() {
136 PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
137 TransactionInterceptor ti = transactionInterceptorWithTransactionManager(transactionManager, null);
138
139 assertSame(transactionManager, ti.determineTransactionManager(null));
140 }
141
142 @Test
143 public void determineTransactionManagerWithNoTransactionAttribute() {
144 BeanFactory beanFactory = mock(BeanFactory.class);
145 TransactionInterceptor ti = simpleTransactionInterceptor(beanFactory);
146
147 assertNull(ti.determineTransactionManager(null));
148 }
149
150 @Test
151 public void determineTransactionManagerWithQualifierUnknown() {
152 BeanFactory beanFactory = mock(BeanFactory.class);
153 TransactionInterceptor ti = simpleTransactionInterceptor(beanFactory);
154 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
155 attribute.setQualifier("fooTransactionManager");
156
157 thrown.expect(NoSuchBeanDefinitionException.class);
158 thrown.expectMessage("'fooTransactionManager'");
159 ti.determineTransactionManager(attribute);
160 }
161
162 @Test
163 public void determineTransactionManagerWithQualifierAndDefault() {
164 BeanFactory beanFactory = mock(BeanFactory.class);
165 PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
166 TransactionInterceptor ti = transactionInterceptorWithTransactionManager(transactionManager, beanFactory);
167 PlatformTransactionManager fooTransactionManager =
168 associateTransactionManager(beanFactory, "fooTransactionManager");
169
170 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
171 attribute.setQualifier("fooTransactionManager");
172
173 assertSame(fooTransactionManager, ti.determineTransactionManager(attribute));
174 }
175
176 @Test
177 public void determineTransactionManagerWithQualifierAndDefaultName() {
178 BeanFactory beanFactory = mock(BeanFactory.class);
179 associateTransactionManager(beanFactory, "defaultTransactionManager");
180 TransactionInterceptor ti = transactionInterceptorWithTransactionManagerName(
181 "defaultTransactionManager", beanFactory);
182
183 PlatformTransactionManager fooTransactionManager =
184 associateTransactionManager(beanFactory, "fooTransactionManager");
185 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
186 attribute.setQualifier("fooTransactionManager");
187
188 assertSame(fooTransactionManager, ti.determineTransactionManager(attribute));
189 }
190
191 @Test
192 public void determineTransactionManagerWithEmptyQualifierAndDefaultName() {
193 BeanFactory beanFactory = mock(BeanFactory.class);
194 PlatformTransactionManager defaultTransactionManager
195 = associateTransactionManager(beanFactory, "defaultTransactionManager");
196 TransactionInterceptor ti = transactionInterceptorWithTransactionManagerName(
197 "defaultTransactionManager", beanFactory);
198
199 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
200 attribute.setQualifier("");
201
202 assertSame(defaultTransactionManager, ti.determineTransactionManager(attribute));
203 }
204
205 @Test
206 public void determineTransactionManagerWithQualifierSeveralTimes() {
207 BeanFactory beanFactory = mock(BeanFactory.class);
208 TransactionInterceptor ti = simpleTransactionInterceptor(beanFactory);
209
210 PlatformTransactionManager txManager = associateTransactionManager(beanFactory, "fooTransactionManager");
211
212 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
213 attribute.setQualifier("fooTransactionManager");
214 PlatformTransactionManager actual = ti.determineTransactionManager(attribute);
215 assertSame(txManager, actual);
216
217
218 PlatformTransactionManager actual2 = ti.determineTransactionManager(attribute);
219 assertSame(txManager, actual2);
220 verify(beanFactory, times(1)).containsBean("fooTransactionManager");
221 verify(beanFactory, times(1)).getBean("fooTransactionManager", PlatformTransactionManager.class);
222 }
223
224 @Test
225 public void determineTransactionManagerWithBeanNameSeveralTimes() {
226 BeanFactory beanFactory = mock(BeanFactory.class);
227 TransactionInterceptor ti = transactionInterceptorWithTransactionManagerName(
228 "fooTransactionManager", beanFactory);
229
230 PlatformTransactionManager txManager = associateTransactionManager(beanFactory, "fooTransactionManager");
231
232 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
233 PlatformTransactionManager actual = ti.determineTransactionManager(attribute);
234 assertSame(txManager, actual);
235
236
237 PlatformTransactionManager actual2 = ti.determineTransactionManager(attribute);
238 assertSame(txManager, actual2);
239 verify(beanFactory, times(1)).getBean("fooTransactionManager", PlatformTransactionManager.class);
240 }
241
242 @Test
243 public void determineTransactionManagerDefaultSeveralTimes() {
244 BeanFactory beanFactory = mock(BeanFactory.class);
245 TransactionInterceptor ti = simpleTransactionInterceptor(beanFactory);
246
247 PlatformTransactionManager txManager = mock(PlatformTransactionManager.class);
248 given(beanFactory.getBean(PlatformTransactionManager.class)).willReturn(txManager);
249
250 DefaultTransactionAttribute attribute = new DefaultTransactionAttribute();
251 PlatformTransactionManager actual = ti.determineTransactionManager(attribute);
252 assertSame(txManager, actual);
253
254
255 PlatformTransactionManager actual2 = ti.determineTransactionManager(attribute);
256 assertSame(txManager, actual2);
257 verify(beanFactory, times(1)).getBean(PlatformTransactionManager.class);
258 }
259
260 private TransactionInterceptor createTransactionInterceptor(BeanFactory beanFactory,
261 String transactionManagerName, PlatformTransactionManager transactionManager) {
262 TransactionInterceptor ti = new TransactionInterceptor();
263 if (beanFactory != null) {
264 ti.setBeanFactory(beanFactory);
265 }
266 if (transactionManagerName != null) {
267 ti.setTransactionManagerBeanName(transactionManagerName);
268
269 }
270 if (transactionManager != null) {
271 ti.setTransactionManager(transactionManager);
272 }
273 ti.setTransactionAttributeSource(new NameMatchTransactionAttributeSource());
274 ti.afterPropertiesSet();
275 return ti;
276 }
277
278 private TransactionInterceptor transactionInterceptorWithTransactionManager(
279 PlatformTransactionManager transactionManager, BeanFactory beanFactory) {
280
281 return createTransactionInterceptor(beanFactory, null, transactionManager);
282 }
283
284 private TransactionInterceptor transactionInterceptorWithTransactionManagerName(
285 String transactionManagerName, BeanFactory beanFactory) {
286
287 return createTransactionInterceptor(beanFactory, transactionManagerName, null);
288 }
289
290 private TransactionInterceptor simpleTransactionInterceptor(BeanFactory beanFactory) {
291 return createTransactionInterceptor(beanFactory, null, null);
292 }
293
294 private PlatformTransactionManager associateTransactionManager(BeanFactory beanFactory, String name) {
295 PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
296 given(beanFactory.containsBean(name)).willReturn(true);
297 given(beanFactory.getBean(name, PlatformTransactionManager.class)).willReturn(transactionManager);
298 return transactionManager;
299 }
300
301
302
303
304
305 @SuppressWarnings("serial")
306 public static class SerializableTransactionManager implements PlatformTransactionManager, Serializable {
307
308 @Override
309 public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
310 throw new UnsupportedOperationException();
311 }
312
313 @Override
314 public void commit(TransactionStatus status) throws TransactionException {
315 throw new UnsupportedOperationException();
316 }
317
318 @Override
319 public void rollback(TransactionStatus status) throws TransactionException {
320 throw new UnsupportedOperationException();
321 }
322
323 }
324 }