Spring data @transactional not rolling back with SQL Server and after runtimeexception

老子叫甜甜 提交于 2020-01-06 03:41:04

问题


I've enabled my spring application to use transactions and annotated my service method accordingly but the changes to my DB persist when a RuntimeException is thrown.

My Spring configuration looks like this:

<!-- Data Source. -->   
<jee:jndi-lookup id="dataSource" jndi-name="java:/jdbc/BeheermoduleDS"/>

<!-- JPA Entity Manager. -->    
<jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/jpa/BeheermoduleDS"/>

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />

My datasource configuration in my jboss' configuration file looks like this:

<datasource jta="true" jndi-name="java:/jdbc/BeheermoduleDS" pool-name="BeheermoduleDS" enabled="true" use-java-context="true" use-ccm="true">
    <connection-url>jdbc:sqlserver://localhost:1433;databaseName=Gebruikers;</connection-url>
    <driver>sqljdbc</driver>
    <security>
        <user-name>jboss</user-name>
        <password>*****</password>
    </security>
</datasource>

My Service method looks like this:

@Transactional
public void authorise(Gebruiker user) {

    user.setStatus(GebruikerStatus.Actief.name());
    gebruikerRepo.save(user);
    if (true) {
        throw new RuntimeException("Exception happened just like that");
    }

    // does more stuff here that is never reached
}

My repository extends a spring data repository and looks like this:

public interface GebruikerRepository extends PagingAndSortingRepository<Gebruiker, Long>, QueryDslPredicateExecutor<Gebruiker> {

}

The transaction is thrown and caught by a controller which just shows a message to the user that an exception occurred. When I check my SQL Server DB, the change made to the user status have been commited.

Weren't they supposed to have been rolled back with the RuntimeException?

After turning debug on for org.springframework.transaction.interceptor I saw that no transactions are being started for my service method, but they are for a bunch of JpaRepository methods.

Also, this is how my persistence.xml looks like:

<persistence-unit name="BeheermodulePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>java:/jdbc/BeheermoduleDS</non-jta-data-source> 

回答1:


Judging from the symptoms you describe you are scanning for the same classes twice. You probably have the same <context:component-scan /> in both the configuration of the ContextLoaderListener and DispatcherServlet.

You want the ContextLoaderListener to scan for everything but @Controller and the DispatcherServlet only for @Controllers. Leading to something like this.

For the ContextLoaderListener

<!-- Load everything except @Controllers -->
<context:component-scan base-package="com.myapp">
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

For the DispatcherServlet

<!-- Load everything except @Controllers -->
<context:component-scan base-package="com.myapp" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

See also @Service are constructed twice for another sample and broader explanation.



来源:https://stackoverflow.com/questions/27624141/spring-data-transactional-not-rolling-back-with-sql-server-and-after-runtimeexc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!