Quartz cannot find transaction with Spring - java

I'm trying to get a clustered, Spring-managed Quartz environment going and I'm running into problems with the transaction features:
2014-02-06 13:59:00,015 ERROR org.quartz.core.ErrorLogger - Error executing Job (DEFAULT.idleDeviceJob: couldn't begin execution.
org.quartz.SchedulerException: UserTransactionHelper could not lookup/create UserTransaction. [See nested exception: javax.naming.NamingException: Cannot create resource instance]
at org.quartz.ee.jta.UserTransactionHelper$UserTransactionWithContext.<init>(UserTransactionHelper.java:148)
at org.quartz.ee.jta.UserTransactionHelper.lookupUserTransaction(UserTransactionHelper.java:108)
at org.quartz.ee.jta.JTAJobRunShell.begin(JTAJobRunShell.java:101)
at org.quartz.core.JobRunShell.run(JobRunShell.java:164)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560)
Caused by: javax.naming.NamingException: Cannot create resource instance
at org.apache.naming.factory.TransactionFactory.getObjectInstance(TransactionFactory.java:116)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at org.quartz.ee.jta.UserTransactionHelper$UserTransactionWithContext.<init>(UserTransactionHelper.java:145)
... 4 more
Obviously as I'm running in Tomcat, there is no JNDI registration for the UserTransaction. That said, I can't figure out how to get Quartz to use the existing transactions I've provided in my application context via AOP (or just ignore the transaction stuff as AOP handles it):
<!-- Quartz Scheduler Transaction Propagation -->
<tx:advice id="quartzSchedulerAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="SUPPORTS" />
<tx:method name="set*" read-only="true" propagation="SUPPORTS" />
<tx:method name="is*" read-only="true" propagation="SUPPORTS" />
<tx:method name="insert*" read-only="false" propagation="REQUIRED"/>
<tx:method name="update*" read-only="false" propagation="REQUIRED"/>
<tx:method name="delete*" read-only="false" propagation="REQUIRED"/>
<tx:method name="schedule*" read-only="false" propagation="REQUIRED" rollback-for="org.quartz.SchedulerException"/>
<tx:method name="pause*" read-only="false" propagation="REQUIRED"/>
<tx:method name="resume*" read-only="false" propagation="REQUIRED"/>
<tx:method name="run*" read-only="false" propagation="REQUIRED"/>
<tx:method name="update*" read-only="false" propagation="REQUIRED"/>
<tx:method name="delete*" read-only="false" propagation="REQUIRED"/>
<tx:method name="toggle*" read-only="false" propagation="REQUIRED"/>
<tx:method name="clone*" read-only="false" propagation="REQUIRED"/>
</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="jdbcDaoPC"
expression="execution(* com.project.repository.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="jdbcDaoPC" />
</aop:config>
<aop:config>
<aop:pointcut id="quartzSchedulerPointcut"
expression="execution(* org.quartz.Scheduler.*(..))" />
<aop:advisor advice-ref="quartzSchedulerAdvice"
pointcut-ref="quartzSchedulerPointcut" />
</aop:config>
I'm using BoneCP as my datasource:
<!-- Row Mapper Beans -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="idleMaxAge" value="240" />
<property name="maxConnectionsPerPartition" value="5" />
<property name="minConnectionsPerPartition" value="2" />
<property name="partitionCount" value="3" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
And my Spring scheduler factory configuration is here:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:quartz.properties"/>
<property name="dataSource" ref="dataSource"/>
<property name="nonTransactionalDataSource">
<bean class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</property>
<property name="transactionManager" ref="txManager"/>
<property name="schedulerName" value="ClusteredScheduler"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="autoStartup" value="true"/>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="jobFactory">
<bean class="com.project.scheduling.persistence.AutowiringSpringBeanJobFactory"/>
</property>
<property name="schedulerContextAsMap">
<map>
<entry key="dataSource" value-ref="dataSource" />
<entry key="transactionManager" value-ref="txManager" />
</map>
</property>
<property name="jobDetails">
<list>
<ref bean="shipNoticeJob" />
<ref bean="idleDeviceJob" />
<ref bean="distanceJob" />
<ref bean="deviceMaintenanceJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="shipNoticeCronTrigger" />
<ref bean="idleDeviceTrigger" />
<ref bean="distanceTrigger" />
<ref bean="deviceMaintenanceTrigger" />
</list>
</property>
</bean>
None of the tutorials etc I've been able to find online reference this issue in Tomcat so I'm left assuming theres a configuration step I'm missing...

Well, this one was staring me in the face:
org.quartz.scheduler.wrapJobExecutionInUserTransaction=true
Should have been:
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
Duh.

Related

Spring not rolled back with a RuntimeException

<!-- 引入外部JDBC配置信息 -->
<context:property-placeholder location="classpath:JDBC.properties" />
<!-- 配置C3P0连接池: -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${DriverClass}" />
<property name="jdbcUrl" value="${URL}" />
<property name="user" value="${USER}" />
<property name="password" value="${PASSWORD}" />
<!-- 其他配置 -->
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="3"></property>
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="5"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:
0 -->
<property name="maxStatements" value="8"></property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection" value="5"></property>
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
<!-- Hibernate的相关信息 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置Hibernate的其他的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置Hibernate的映射文件 -->
<property name="mappingLocations" value="classpath:*.hbm.xml">
</property>
</bean>
<!-- 事务管理: -->
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务通知属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定义事务传播属性 -->
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.fjx.service.*.*(..))"
id="servicePointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
</aop:config>
<bean id="roleDao" class="com.fjx.dao.RoleDao">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="roleService" class="com.fjx.service.RoleService">
<property name="roleDao" ref="roleDao"></property>
</bean>
roleService文件如下:
public class RoleService {
private RoleDao roleDao;
public void save(Role role){
roleDao.save(role);
}
public void setRoleDao(RoleDao roleDao) {
this.roleDao = roleDao;
}
}
junit测试类如下:
#Test
public void saveTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
RoleService roleService = (RoleService) applicationContext.getBean("roleService");
Role role = new Role();
role.setRname("11");
role.setRdescription("1111");
int i = 1/0;
roleService.save(role);
Role role1 = new Role();
role1.setRname("11");
role1.setRdescription("1111");
roleService.save(role1);
}
There is an Exception, but the role is saved successfully.It is not rollbacked, i can not find out the question...

Cannot convert value of type to required type [org.springframework.aop.Pointcut]

I am trying to setup Spring transaction management for Hibernate however, I meet the following issue...
java.lang.IllegalArgumentException: Cannot convert value of type [ac.nz.unitec.service.impl.UserServiceImpl] to required type [org.springframework.aop.Pointcut] for property 'pointcut': no matching editors or conversion strategy found
Here are more details and the Spring configuration
There is an interface called UserService and UserServiceImpl implements the interface.
Spring Configuration:
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="userService"
expression="execution(public * ac.nz.unitec.service.UserService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userService" />
</aop:config>
<!--I also tried the following one but didn't work out either-->
<aop:config>
<aop:pointcut id="userService"
expression="execution(public * ac.nz.unitec.service.impl.UserServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userService" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="exist" />
<tx:method name="add" />
</tx:attributes>
</tx:advice>
<!--Not sure whether the following piece matters as it has duplicate name with the one in aop config-->
<bean name="userService" class="ac.nz.unitec.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
Updated Spring Configuration xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<aop:aspectj-autoproxy />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>ac/nz/unitec/model/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="userServiceOperation"
expression="execution(* ac.nz.unitec.service.UserService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServiceOperation" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="exist" />
<tx:method name="add" />
</tx:attributes>
</tx:advice>
<bean name="userAction" class="ac.nz.unitec.action.UserAction" scope="prototype">
<property name="userService" ref="userService"/>
</bean>
<bean name="retrieveAction" class="ac.nz.unitec.action.RetrieveAction" scope="prototype">
<property name="userService" ref="userService"/>
</bean>
<bean id="userService" class="ac.nz.unitec.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean name="userDao" class="ac.nz.unitec.dao.impl.UserDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
</beans>
Really appreciated for any suggestions, thanks ahead
In the old config file, in aop:config, the aop:pointcut id is userService. However, there is a bean whose name is also userService. I changed the aop:pointcut id to userServiceOperation and it fixed the issue

Spring #Transactional annotation does not roll back

My #Transactional annotation doesn't rollback the first insert when the second update sentence fails (with a non-RuntimeException). The exception is launched in updateNumeroVotos but Spring doesn't rollback the insert of save operation.
Any idea?
I have these files:
IdeaService.java code:
#Service
public class IdeasServiceImpl implements IdeasService {
#Autowired
all daos code
/**
* Metodo que inserta un voto de un usuario
*/
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void incorporarVoto(String token, Integer id) throws Exception {
IdeaVotoVO ideaVoto = new IdeaVotoVO();
ideaVoto.setUsuario(usuariosService.getDatosTokenUsuario(token).getLoginCiudadano());
ideaVoto.setIdIdea(id);
ideaVoto.setVoto(ConstantesModel.IDEA_VOTO_POSITIVO);
if (validarVoto(ideaVoto)) {
ideaVotoDAO.save(ideaVoto);
ideaDatosDao.updateNumeroVotos(new Timestamp(Generic.getFechaActual()), id);
}
}
applicationContext.xml
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<context:component-scan base-package="example.code.xxxx.*" />
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#ora11g:1521:xxxxxx" />
<property name="username" value="xxxxxx" />
<property name="password" value="yyyyy" />
<property name="validationQuery" value="SELECT SYSDATE FROM DUAL" />
<property name="maxIdle" value="3" />
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="100" />
<property name="maxWaitMillis" value="10000" />
<property name="maxTotal" value="20" />
</bean>
<bean id="sessionFactoryCiud"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
<property name="mappingResources">
<list>
<<--Here de entity's-->
</list>
</property>
</bean>
<cache:annotation-driven />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache" />
</bean>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:ehcache.xml" />
<bean id="TransactionManagerCiud"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactoryCiud" />
<qualifier value="ciudada" />
</bean>
<tx:annotation-driven transaction-manager="TransactionManagerCiud" proxy-target-class="true"/>
<bean id="ideasService"
class="example.code.xxxx.service.ideas.impl.IdeasServiceImpl">
</bean>
<bean id="IdeaVotoDAO"
class="example.code.xxxx.model.ideas.impl.IdeaVotoDAOImpl">
<property name="sessionFactory" ref="sessionFactoryCiudadania" />
</bean>
<bean id="IdeaDatosDAO"
class="example.code.xxxx.model.ideas.impl.IdeaDatosDAOImpl">
<property name="sessionFactory" ref="sessionFactoryCiud" />
</bean>
</beans>
I tried to add this lines but it dont work
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
Then, please add:
rollbackFor = Exception.class
to your #Transactional annotation.
EDIT:
If you don't want to edit each of your #Transactional annotatinos, please look at this interesting approach.
From the start a good design would be, if (all of) your services would throw (a customized type of) RuntimeException, when something rollbackable happens. (But this seems more complex than modifying all annotations.)
You can provide tx:advices for the transaction managers like this:
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
(as explained in the documentation.)
What is "sessionFactoryCiudadania" used by "ideaVotoDao" and why is it different from the SessionFactory used by your transaction manager? The annotation is only going to rollback content from the session that it created.... If a DAO is using a different session internally it's going to commit based on its own rules (which probably means basic autoCommit mode.)

access denied in spring application on GAE

from a couple of days my application deployed on GAE was in error with the message
ERROR:Context initialization failed
org.springframework.web.context.ContextLoader[ContextLoader.java:215 2015-03-13 16:48:42,389#Request E088823F)
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager'
defined in ServletContext resource [/WEB-INF/config/modulo-spring.xml]:
Cannot resolve reference to bean 'fabbricaSessioni'
while setting bean property 'entityManagerFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'fabbricaSessioni':
Post-processing of the FactoryBean's object failed;
nested exception is java.security.AccessControlException:
access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.proxy")
seems like Google has made some update that fails the spring's proxy creation.
I've searched a lot, but I haven't found anything....
this is my applicationcontext.xml
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory">
<ref local="fabbricaSessioni" />
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.GoogleDriver" />
<property name="url" value="jdbc:google:mysql://xxxxx"/>
</bean>
<bean id="fabbricaSessioni" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" scope="singleton">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="persistenceUnitName" value="hib-persistence" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
<property name="jpaProperties">
<props>
[hibernate props]
</props>
</property>
</bean>
<tx:advice id="advice1" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="search*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="advice1" pointcut="execution(* org.somepackage.*.*(..))" />
<aop:advisor advice-ref="advice1" pointcut="execution(* org.otherpackage.someclass.*(..))" />
</aop:config>
any help is appreciated

How to make service use particular txAdvice in Spring?

I'm trying to upgrade my project and so I've come to transactions. This is how I did it up to now.
<bean id="userServiceTarget" class="com.forgin.service.UserServiceImpl">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="userServiceTarget" />
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_SUPPORTS</prop>
<prop key="is*">PROPAGATION_SUPPORTS</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
I changed the transaction attributes like this bellow, but I'm not quite sure how could I link the service with exactly this txAdvice. Cause I generally have different transaction attributes for different services so there I guess should be more than one txAdvice. Is there a way how to say the #Transactional to use this particular txAdvice?
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="is*" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
Alright, I figured out it.. it just came to me. Haha.. I just need to provide additional aop:advisor and aop:pointcut. As simple as that.
<aop:config>
<aop:pointcut id="userOperation"
expression="execution(* com.forgin.service.UserServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
<aop:pointcut id="differentOperation"
expression="execution(* com.forgin.service.DifferentServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdviceDifferent" pointcut-ref="differentOperation" />
</aop:config>

Categories

Resources