Spring not rolled back with a RuntimeException - java

<!-- 引入外部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...

Related

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

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode

I'm new to SSH, and I'm using Spring 4, Hibernate 4 and Struts 2.
When I create a unit testing for a DAO class, I got this exception.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class UserDaoTest {
#Test
public void testAddUserNotExists() {
User user = new User("20116524", "785ee107c11dfe36de668b1ae7baacbb");
userDao.addUser(user);
assertNotNull(userDao.getUserByUsername("20116524"));
}
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
/**
* UserDao object to test.
*/
private UserDao userDao;
}
I tried to add following lines to web.xml, but it doesn't work.
Reference: Java / Hibernate - Write operations are not allowed in read-only mode
I believe there's something wrong with my applicationContext.xml, and here's the content:
<!-- Session Factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>emis.accounts.model</value>
</list>
</property>
</bean>
<!-- Transaction -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
There's no configuration about AOP and tx:advice. So I tried to add some lines:
<!-- Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="list*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="save" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy />
<aop:config>
<aop:pointcut id="aopPointcut"
expression="execution(* emis.*.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="aopPointcut"/>
</aop:config>
However, I got another exception:
WARNING: Exception thrown from ApplicationListener handling ContextClosedEvent
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: Root WebApplicationContext: startup date [Thu Mar 20 13:53:51 CST 2014]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:346)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:880)
...
WARNING: Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: Root WebApplicationContext: startup date [Thu Mar 20 13:53:51 CST 2014]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:359)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:888)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:841)
...
What should I do? Can anyone help me? Thanks a lot!!
First make up your mind on what you want to use for transactions. XML configuration or annotations #Transactional. Don't try to mix both of them.
If you use #Transactional make sure that your UserDao is annotated with the correct annotations.
If you use XML make sure that you have the ordering inside the tx:advice correct. Currently everything is read-only. The first match wins, as you have a wildcard * on top everything will match that pointcut. Next you don't need the <aop:aspectj-autoproxy /> as you have declared your aspect with an <aop:config /> block.

Quartz cannot find transaction with Spring

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.

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