/** * Test the important case where the invocation is on a proxied interface method * but the attribute is defined on the target class. */ @Test public void transactionAttributeDeclaredOnCglibClassMethod() throws Exception { Method classMethod = ITestBean.class.getMethod("getAge"); TestBean1 tb = new TestBean1(); ProxyFactory pf = new ProxyFactory(tb); pf.setProxyTargetClass(true); Object proxy = pf.getProxy(); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(classMethod, proxy.getClass()); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
/** * Test that when an attribute exists on both class and interface, class takes precedence. */ @Test public void transactionAttributeOnTargetClassMethodOverridesAttributeOnInterfaceMethod() throws Exception { Method interfaceMethod = ITestBean3.class.getMethod("getAge"); Method interfaceMethod2 = ITestBean3.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRES_NEW, actual.getPropagationBehavior()); assertEquals(TransactionAttribute.ISOLATION_REPEATABLE_READ, actual.getIsolationLevel()); assertEquals(5, actual.getTimeout()); assertTrue(actual.isReadOnly()); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); TransactionAttribute actual2 = atas.getTransactionAttribute(interfaceMethod2, TestBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, actual2.getPropagationBehavior()); }
@Test public void customClassAttributeWithReadOnlyOverrideOnInterface() throws Exception { Method method = TestInterface9.class.getMethod("getAge"); Transactional annotation = AnnotationUtils.findAnnotation(method, Transactional.class); assertNull("AnnotationUtils.findAnnotation should not find @Transactional for TestBean9.getAge()", annotation); annotation = AnnotationUtils.findAnnotation(TestBean9.class, Transactional.class); assertNotNull("AnnotationUtils.findAnnotation failed to find @Transactional for TestBean9", annotation); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean9.class); assertNotNull("Failed to retrieve TransactionAttribute for TestBean9.getAge()", actual); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); assertTrue(actual.isReadOnly()); }
@Test public void customMethodAttributeWithReadOnlyOverrideOnInterface() throws Exception { Method method = TestInterface10.class.getMethod("getAge"); Transactional annotation = AnnotationUtils.findAnnotation(method, Transactional.class); assertNotNull("AnnotationUtils.findAnnotation failed to find @Transactional for TestBean10.getAge()", annotation); annotation = AnnotationUtils.findAnnotation(TestBean10.class, Transactional.class); assertNull("AnnotationUtils.findAnnotation should not find @Transactional for TestBean10", annotation); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean10.class); assertNotNull("Failed to retrieve TransactionAttribute for TestBean10.getAge()", actual); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); assertTrue(actual.isReadOnly()); }
@Autowired private void setTransactionTemplate(PlatformTransactionManager transactionManager) { DefaultTransactionAttribute writeTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED); writeTransactionAttribute.setReadOnly(false); writeTransactionTemplate = new TransactionTemplate(transactionManager, writeTransactionAttribute); DefaultTransactionAttribute writeRequiresNewTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRES_NEW); writeRequiresNewTransactionAttribute.setReadOnly(false); writeRequiresNewTransactionTemplate = new TransactionTemplate(transactionManager, writeRequiresNewTransactionAttribute); DefaultTransactionAttribute readOnlyTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED); readOnlyTransactionAttribute.setReadOnly(true); readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, readOnlyTransactionAttribute); }
/** * 获得 map for LOGGER. * * @param transactionAttribute * the transaction attribute * @return the map for log */ public static final Map<String, Object> getMapForLog(TransactionAttribute transactionAttribute){ if (null == transactionAttribute){ return null; } int isolationLevel = transactionAttribute.getIsolationLevel(); String isolationLevelString = ISOLATION_LEVEL_AND_NAME_MAP.get(isolationLevel); int propagationBehavior = transactionAttribute.getPropagationBehavior(); String propagationBehaviorString = PROPAGATION_BEHAVIOR_AND_NAME_MAP.get(propagationBehavior); Map<String, Object> map = newLinkedHashMap(); map.put("getPropagationBehavior", propagationBehaviorString + "(" + propagationBehavior + ")"); map.put("getIsolationLevel", isolationLevelString + "(" + isolationLevel + ")"); map.put("isReadOnly", transactionAttribute.isReadOnly()); map.put("getName", transactionAttribute.getName()); map.put("getQualifier", transactionAttribute.getQualifier()); map.put("getTimeout", transactionAttribute.getTimeout()); return map; }
/** * 判断数据库读写类型,<br> * 通过 {@link org.springframework.transaction.interceptor.TransactionAttribute}判断这次请求该操作读库还是写库. * * @param transactionAttribute * the transaction attribute * @return the read write support * @see "org.postgresql.jdbc2.AbstractJdbc2Connection#setReadOnly(boolean)" * @since 1.1.1 */ private static String getReadWriteSupport(TransactionAttribute transactionAttribute){ if (null == transactionAttribute){ return READ; } boolean mustWrite = PROPAGATION_BEHAVIOR_AND_MUST_WRITE_MAP.get(transactionAttribute.getPropagationBehavior()); if (mustWrite){ LOGGER.info("New writable connection is required for new transaction."); return WRITE; } //see "org.postgresql.jdbc2.AbstractJdbc2Connection#setReadOnly(boolean)" boolean readOnly = transactionAttribute.isReadOnly(); return readOnly ? READ : WRITE; }
@Override public TransactionAttributeSource getTransactionAttributeSource() { final TransactionAttributeSource origTxAttrSource = super.getTransactionAttributeSource(); return new TransactionAttributeSource() { @Override public TransactionAttribute getTransactionAttribute(final Method method, final Class<?> targetClass) { TransactionAttribute txAttr = origTxAttrSource.getTransactionAttribute(method, targetClass); if (txAttr instanceof DefaultTransactionAttribute) { ((DefaultTransactionAttribute) txAttr).setQualifier(AuthContextUtils.getDomain()); } return txAttr; } }; }
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { Ldtm ldtmAnn = AnnotationUtils.getAnnotation(ae, Ldtm.class); if(ldtmAnn != null){ LdtmTransactionAttribute att = new LdtmTransactionAttribute(); att.setTimeout(ldtmAnn.timeout()); return att; }else{ //使用兼容模式时使用的方法,兼容模式见使用TransactionManager来进行ldtm的事务处理 Transactional ann = AnnotationUtils.getAnnotation(ae, Transactional.class); if (advisor != null && ann != null) { //如果确定的transactionManager是一个ldtm的transactionManager的话就可以进行拦截 PlatformTransactionManager transactionManager = determineTransactionManager(ann.value()); if(transactionManager instanceof LdtmPlatformTransactionManager){ //这个对象将不会有任何类进行处理,只是为了标示这是需要进行拦截 return new DefaultTransactionAttribute(); } } } return null; }
/** * Test the important case where the invocation is on a proxied interface method * but the attribute is defined on the target class. */ @Test public void testTransactionAttributeDeclaredOnCglibClassMethod() throws Exception { Method classMethod = ITestBean.class.getMethod("getAge", (Class[]) null); TestBean1 tb = new TestBean1(); ProxyFactory pf = new ProxyFactory(tb); pf.setProxyTargetClass(true); Object proxy = pf.getProxy(); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(classMethod, proxy.getClass()); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
/** * Test that when an attribute exists on both class and interface, class takes precedence. */ @Test public void testTransactionAttributeOnTargetClassMethodOverridesAttributeOnInterfaceMethod() throws Exception { Method interfaceMethod = ITestBean3.class.getMethod("getAge", (Class[]) null); Method interfaceMethod2 = ITestBean3.class.getMethod("getName", (Class[]) null); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRES_NEW, actual.getPropagationBehavior()); assertEquals(TransactionAttribute.ISOLATION_REPEATABLE_READ, actual.getIsolationLevel()); assertEquals(5, actual.getTimeout()); assertTrue(actual.isReadOnly()); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); TransactionAttribute actual2 = atas.getTransactionAttribute(interfaceMethod2, TestBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, actual2.getPropagationBehavior()); }
@Override public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ae, javax.transaction.Transactional.class.getName()); if (ann != null) { return parseTransactionAnnotation(ann); } else { return null; } }
@Override public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes ann = AnnotatedElementUtils.getAnnotationAttributes(ae, Transactional.class.getName()); if (ann != null) { return parseTransactionAnnotation(ann); } else { return null; } }
@Override public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { javax.ejb.TransactionAttribute ann = ae.getAnnotation(javax.ejb.TransactionAttribute.class); if (ann != null) { return parseTransactionAnnotation(ann); } else { return null; } }
/** * 读取事务管理中的策略 * * @param txAdvice * @throws Exception */ @SuppressWarnings("unchecked") public void setTxAdvice(TransactionInterceptor txAdvice) throws Exception { if (txAdvice == null) { // 没有配置事务管理策略 return; } // 从txAdvice获取到策略配置信息 TransactionAttributeSource transactionAttributeSource = txAdvice.getTransactionAttributeSource(); if (!(transactionAttributeSource instanceof NameMatchTransactionAttributeSource)) { return; } // 使用反射技术获取到NameMatchTransactionAttributeSource对象中的nameMap属性值 NameMatchTransactionAttributeSource matchTransactionAttributeSource = (NameMatchTransactionAttributeSource) transactionAttributeSource; Field nameMapField = ReflectionUtils.findField(NameMatchTransactionAttributeSource.class, "nameMap"); nameMapField.setAccessible(true); // 设置该字段可访问 // 获取nameMap的值 Map<String, TransactionAttribute> map = (Map<String, TransactionAttribute>) nameMapField.get(matchTransactionAttributeSource); // 遍历nameMap for (Map.Entry<String, TransactionAttribute> entry : map.entrySet()) { if (!entry.getValue().isReadOnly()) {// 判断之后定义了ReadOnly的策略才加入到slaveMethodPattern continue; } slaveMethodPattern.add(entry.getKey()); } }
/** * Determine the transaction attribute for the given method or class. * <p>This implementation delegates to configured * {@link TransactionAnnotationParser TransactionAnnotationParsers} * for parsing known annotations into Spring's metadata attribute class. * Returns {@code null} if it's not transactional. * <p>Can be overridden to support custom annotations that carry transaction metadata. * @param ae the annotated method or class * @return TransactionAttribute the configured transaction attribute, * or {@code null} if none was found */ protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) { if (ae.getAnnotations().length > 0) { for (TransactionAnnotationParser annotationParser : this.annotationParsers) { TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae); if (attr != null) { return attr; } } } return null; }
@Override public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, javax.transaction.Transactional.class); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } }
@Override public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } }
/** * Test the important case where the invocation is on a proxied interface method * but the attribute is defined on the target class. */ @Test public void transactionAttributeDeclaredOnClassMethod() throws Exception { Method classMethod = ITestBean.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(classMethod, TestBean1.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
/** * Test case where attribute is on the interface method. */ @Test public void transactionAttributeDeclaredOnInterfaceMethodOnly() throws Exception { Method interfaceMethod = ITestBean2.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean2.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
/** * Test that transaction attribute is inherited from class * if not specified on method. */ @Test public void defaultsToClassTransactionAttribute() throws Exception { Method method = TestBean4.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean4.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
@Test public void customClassAttributeDetected() throws Exception { Method method = TestBean5.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean5.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
@Test public void customMethodAttributeDetected() throws Exception { Method method = TestBean6.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean6.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); }
@Test public void customClassAttributeWithReadOnlyOverrideDetected() throws Exception { Method method = TestBean7.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean7.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); assertTrue(actual.isReadOnly()); }
@Test public void customMethodAttributeWithReadOnlyOverrideDetected() throws Exception { Method method = TestBean8.class.getMethod("getAge"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute actual = atas.getTransactionAttribute(method, TestBean8.class); RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class)); rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class)); assertEquals(rbta.getRollbackRules(), ((RuleBasedTransactionAttribute) actual).getRollbackRules()); assertTrue(actual.isReadOnly()); }
@Test public void transactionAttributeDeclaredOnClassMethodWithEjb3() throws Exception { Method getAgeMethod = ITestBean.class.getMethod("getAge"); Method getNameMethod = ITestBean.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean1.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean1.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void transactionAttributeDeclaredOnClassWithEjb3() throws Exception { Method getAgeMethod = ITestBean.class.getMethod("getAge"); Method getNameMethod = ITestBean.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean2.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean2.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void transactionAttributeDeclaredOnInterfaceWithEjb3() throws Exception { Method getAgeMethod = ITestEjb.class.getMethod("getAge"); Method getNameMethod = ITestEjb.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, Ejb3AnnotatedBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, Ejb3AnnotatedBean3.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void transactionAttributeDeclaredOnClassMethodWithJta() throws Exception { Method getAgeMethod = ITestBean.class.getMethod("getAge"); Method getNameMethod = ITestBean.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, JtaAnnotatedBean1.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, JtaAnnotatedBean1.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void transactionAttributeDeclaredOnClassWithJta() throws Exception { Method getAgeMethod = ITestBean.class.getMethod("getAge"); Method getNameMethod = ITestBean.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, JtaAnnotatedBean2.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, JtaAnnotatedBean2.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void transactionAttributeDeclaredOnInterfaceWithJta() throws Exception { Method getAgeMethod = ITestEjb.class.getMethod("getAge"); Method getNameMethod = ITestEjb.class.getMethod("getName"); AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); TransactionAttribute getAgeAttr = atas.getTransactionAttribute(getAgeMethod, JtaAnnotatedBean3.class); assertEquals(TransactionAttribute.PROPAGATION_REQUIRED, getAgeAttr.getPropagationBehavior()); TransactionAttribute getNameAttr = atas.getTransactionAttribute(getNameMethod, JtaAnnotatedBean3.class); assertEquals(TransactionAttribute.PROPAGATION_SUPPORTS, getNameAttr.getPropagationBehavior()); }
@Test public void rollbackRules() { TransactionInterceptor txInterceptor = (TransactionInterceptor) context.getBean("txRollbackAdvice"); TransactionAttributeSource txAttrSource = txInterceptor.getTransactionAttributeSource(); TransactionAttribute txAttr = txAttrSource.getTransactionAttribute(getAgeMethod,ITestBean.class); assertTrue("should be configured to rollback on Exception",txAttr.rollbackOn(new Exception())); txAttr = txAttrSource.getTransactionAttribute(setAgeMethod, ITestBean.class); assertFalse("should not rollback on RuntimeException",txAttr.rollbackOn(new RuntimeException())); }
/** * If the test method of the supplied {@linkplain TestContext test context} * is configured to run within a transaction, this method will run * {@link BeforeTransaction @BeforeTransaction} methods and start a new * transaction. * <p>Note that if a {@code @BeforeTransaction} method fails, any remaining * {@code @BeforeTransaction} methods will not be invoked, and a transaction * will not be started. * @see org.springframework.transaction.annotation.Transactional * @see #getTransactionManager(TestContext, String) */ @Override public void beforeTestMethod(final TestContext testContext) throws Exception { final Method testMethod = testContext.getTestMethod(); final Class<?> testClass = testContext.getTestClass(); Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null"); TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext(); if (txContext != null) { throw new IllegalStateException("Cannot start a new transaction without ending the existing transaction."); } PlatformTransactionManager tm = null; TransactionAttribute transactionAttribute = this.attributeSource.getTransactionAttribute(testMethod, testClass); if (transactionAttribute != null) { transactionAttribute = TestContextTransactionUtils.createDelegatingTransactionAttribute(testContext, transactionAttribute); if (logger.isDebugEnabled()) { logger.debug("Explicit transaction definition [" + transactionAttribute + "] found for test context " + testContext); } if (transactionAttribute.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) { return; } tm = getTransactionManager(testContext, transactionAttribute.getQualifier()); } if (tm != null) { txContext = new TransactionContext(testContext, tm, transactionAttribute, isRollback(testContext)); runBeforeTransactionMethods(testContext); txContext.startTransaction(); TransactionContextHolder.setCurrentTransactionContext(txContext); } }
/** * Note: resolution does not occur. Thus we can't make a class transactional if * it implements a transactionally annotated interface. This behaviour could only * be changed in AbstractFallbackTransactionAttributeSource in Spring proper. */ public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws Exception { AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource(); Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class); TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class); assertNull(ta); }
/** * @see org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource#getTransactionAttribute(java.lang.reflect.Method, * java.lang.Class) */ @Override public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) { TransactionAttribute transactionAttribute = annotationTransactionAttributeSource.getTransactionAttribute(method, targetClass); if (transactionAttribute != null) { TransactionAttribute overridingTransactionAttribute = super.getTransactionAttribute(method, targetClass); if (overridingTransactionAttribute != null) { transactionAttribute = overridingTransactionAttribute; } } setTimeout(transactionAttribute); return transactionAttribute; }
/** * If the TransactionAttribute has a setTimeout() method, then this method will invoke it and pass the configured * transaction timeout. This is to allow for proper setting of the transaction timeout on a JTA transaction. */ protected void setTimeout(TransactionAttribute transactionAttribute) { try { if (transactionTimeout != null) { PropertyUtils.setSimpleProperty(transactionAttribute, "timeout", new Integer(transactionTimeout)); } } catch (Exception e) { // failed to set the timeout } }
@Autowired @Lazy // Mutable properties may require a more complex infrastructure, whose setup may require access to immutable properties public void setPlatformTransactionManager(PlatformTransactionManager transactionManager) { DefaultTransactionAttribute writeTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED); writeTransactionAttribute.setReadOnly(false); writeTransactionTemplate = new TransactionTemplate(transactionManager, writeTransactionAttribute); }
@Autowired public void setPlatformTransactionManager(PlatformTransactionManager transactionManager) { DefaultTransactionAttribute readOnlyTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRES_NEW); readOnlyTransactionAttribute.setReadOnly(true); readOnlyTransactionTemplate = new TransactionTemplate(transactionManager, readOnlyTransactionAttribute); DefaultTransactionAttribute writeTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRES_NEW); writeTransactionAttribute.setReadOnly(false); writeTransactionTemplate = new TransactionTemplate(transactionManager, writeTransactionAttribute); }
@Autowired public void setPlatformTransactionManager(PlatformTransactionManager transactionManager) { DefaultTransactionAttribute writeRequiredTransactionAttribute = new DefaultTransactionAttribute(TransactionAttribute.PROPAGATION_REQUIRED); writeRequiredTransactionAttribute.setReadOnly(false); writeRequiredTransactionTemplate = new TransactionTemplate(transactionManager, writeRequiredTransactionAttribute); }