On Fri, 23 May 2014, Andrew Morgan wrote:

> On Thu, 22 May 2014, Marvin Addison wrote:
>
>>> The stack trace indicates that some Spring AOP proxy is intercepting the
>>> I see that createTicketGrantingTicket() has an @Transactional annotation 
>>> applied to
>>> it.  Could this be causing the spurious calls to autocommit and commit?
>> 
>> Yes, I think that's it. I would recommend trying to restrict the scope
>> of Spring AOP transactional proxies to just the service registry. I've
>> never seen that done, but <aop:aspectj-autoproxy> takes a subelement,
>> <include> [1] that is a regex where you can specify the scope of
>> included components. I can imagine a regex that would include
>> ServiceRegistryDao but exclude CentralAuthetnicationServiceImpl. Try
>> that and report back.
>> 
>> M
>> 
>> [1] http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
>
> I played around with various forms on <include> on the 
> <aop:aspectj-autoproxy>, but nothing I did made it stop calling autocommit 
> and commit.  Eventually, I even commented out the <aop:aspectj-autoproxy/> 
> line entirely, but it was *still* calling autocommit and commit.
>
> After getting some help from my coworker, I tried commenting out the 
> transactionManager in deployerConfigContext.xml entirely:
>
> <!-- <tx:annotation-driven transaction-manager="transactionManager"/> -->
>
> This finally stopped CAS from calling autocommit and commit during 
> authentication.
>
> I think the <aop:aspectj-autoproxy> configuration is irrelevant because the 
> transaction manager is automatically adding transactions via the @Transaction 
> annotations.
>
> I'm going to investigate if I can use declarative transactions using XML 
> instead of relying on the annotations.
>
>  
> http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative

Success!

I commented out the tx:annotation-driven configuration from 
deployerConfigContext.xml and added declarative transactions for the 2 
methods that I think need them.  I have attached a diff file showing the 
changes I made.

The two methods that are wrapped in transactions are:

   org.jasig.cas.services.ServicesManager.delete
   org.jasig.cas.services.ServicesManager.save

With these changes in place, I can take MySQL offline and authentications 
still proceed normally.  Packet captures show that no calls to MySQL are 
made during authentication.  Whenever I edit a service, it is still 
correctly wrapped in a transaction (autocommit=0, SQL, SQL, SQL, commit, 
autocommit=1).

I'm not a Java programmer, and I had to learn this AOP and transaction 
stuff on the fly, so my next suggestion may be wrong.  I think the 
underlying problem in the code is that @Transaction annotations were 
placed at the wrong layer, on the methods in class 
CentralAuthenticationServiceImpl.  I think the annotations should be 
placed at lower levels, such as in class JpaTicketRegistry (it's already 
there).  Is there a reason to apply @Transaction at the top-level?  Not 
all ticket registries are transactional (such as memcache).

I couldn't find an old enough version of the 
CentralAuthenticationServiceImpl in github to see when those annotations 
were added, so I have no idea if there is a good reason to have them.  :)

Thoughts?

Thanks,
        Andy
-- 
You are currently subscribed to [email protected] as: 
[email protected]
To unsubscribe, change settings or access archives, see 
http://www.ja-sig.org/wiki/display/JSG/cas-user
--- /tmp/deployerConfigContext.xml	2013-11-07 15:48:06.000000000 -0800
+++ deployerConfigContext.xml	2014-05-28 16:07:50.000000000 -0700
@@ -38,8 +38,10 @@
        xmlns:p="http://www.springframework.org/schema/p";
        xmlns:tx="http://www.springframework.org/schema/tx";
        xmlns:sec="http://www.springframework.org/schema/security";
+       xmlns:aop="http://www.springframework.org/schema/aop";
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
+       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd";>
 	<!--
 		| This bean declares our AuthenticationManager.  The CentralAuthenticationService service bean
@@ -265,7 +267,28 @@
 	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
 		p:entityManagerFactory-ref="entityManagerFactory" />
 
-	<tx:annotation-driven transaction-manager="transactionManager"/>
+  <!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
+  <tx:advice id="txAdvice" transaction-manager="transactionManager">
+  <!-- the transactional semantics... -->
+  <tx:attributes>
+    <!-- all methods starting with 'get' are read-only -->
+    <tx:method name="delete" read-only="false"/>
+    <tx:method name="save" read-only="false"/>
+    <!-- other methods use the default transaction settings (see below) -->
+    <tx:method name="*"/>
+  </tx:attributes>
+  </tx:advice>
+
+  <!-- ensure that the above transactional advice runs for any execution
+    of an operation defined by the FooService interface -->
+  <aop:config>
+  <aop:pointcut id="servicesManagerDelete" expression="execution(* org.jasig.cas.services.ServicesManager.delete(..))"/>
+  <aop:pointcut id="servicesManagerSave" expression="execution(* org.jasig.cas.services.ServicesManager.save(..))"/>
+  <aop:advisor advice-ref="txAdvice" pointcut-ref="servicesManagerDelete"/>
+  <aop:advisor advice-ref="txAdvice" pointcut-ref="servicesManagerSave"/>
+  </aop:config>
+
+<!--	<tx:annotation-driven transaction-manager="transactionManager"/> -->
 
 
 	<!--

Reply via email to