简体   繁体   中英

Why my spring transaction manager for jdbc is not working?

I have config the transaction manager for JDBC, but when I do this:

dao.insert(something);
throw new UnsupportedOperationException();

the transaction doesn't rollback

<aop:aspectj-autoproxy />

<!-- define JDBC datasource by DBCP -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/ts" />
        <property name="username" value="root" />
        <property name="password" value="1234" />
    </bean>

    <!--  DataSourceTransactionManager for jdbc -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="fooDao" class="com.oolong.dao.FooDao">
        <property name="dstm" ref="txManager"></property>
    </bean>

    <bean id="fooService" class="com.oolong.service.DefaultFooService">
        <property name="fooDao" ref="fooDao"></property>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true" propagation="REQUIRED"/>
            <tx:method name="*" read-only="false"  propagation="REQUIRED" 
                rollback-for="java.lang.RuntimeException"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="fooServiceOperation" expression="execution(* com.oolong.service.FooService.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
    </aop:config>

It's a simple example, a DefaultFooService implements the FooService interface. The service has a dao, FooDao, has a method will insert a record into a table.

When I run the code. The transaction haven't been created! of course can't roll back.

FooService interface

package com.oolong.service;

import com.oolong.model.Foo;

public interface FooService {

    Foo getFoo(String fooName);

    Foo getFoo(String fooName, String barName);

    void insertFoo(Foo foo);

    void updateFoo(Foo foo);
}

DefaultFooService.java

package com.oolong.service;

import com.oolong.dao.FooDao;
import com.oolong.model.Foo;

public class DefaultFooService implements FooService {

    private FooDao fooDao;

    public void setFooDao(FooDao fooDao) {
        this.fooDao = fooDao;
    }

    public Foo getFoo(String fooName) {

        throw new UnsupportedOperationException();
    }

    public Foo getFoo(String fooName, String barName) {
        throw new UnsupportedOperationException();
    }

    public void insertFoo(Foo foo) {
        fooDao.insert();
        throw new UnsupportedOperationException();
    }

    public void updateFoo(Foo foo) {
        throw new UnsupportedOperationException();
    }
}

FooDao.java

package com.oolong.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;

public class FooDao {

    private DataSourceTransactionManager dstm;

    public void setDstm(DataSourceTransactionManager dstm) {
        this.dstm = dstm;
    }

    public void insert() {
        try {
            DataSource ds = dstm.getDataSource();
            Connection conn = ds.getConnection();

            String sql = "insert into item (wid, answer, isCorrect, choiceWid) "
                    + "values ('1', '1', 1, '1')";

            Statement st = conn.createStatement();
            st.executeUpdate(sql);

        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

AppContainer.java

public class AppContainer {

    public static void main(final String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/beans.xml", AppContainer.class);
        FooService fooService = (FooService) ctx.getBean("fooService");
        fooService.insertFoo(new Foo());
    }
}

The information log4j output before throw the UnsupportedOperationException:

Loaded NamespaceHandler mappings: {http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler, http://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler, http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler, http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler, http://www.springframework.org/schema/websocket=org.springframework.web.socket.config.WebSocketNamespaceHandler, http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler, http://www.springframework.org/schema/oxm=org.springframework.oxm.config.OxmNamespaceHandler, http://www.springframework.org/schema/jdbc=org.springframework.jdbc.config.JdbcNamespaceHandler, http://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler, http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler, http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler, http://www.springframework.org/schema/jms=org.springframework.jms.config.JmsNamespaceHandler, http://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler, http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler, http://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler}
Creating shared instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
Creating instance of bean 'org.springframework.aop.config.internalAutoProxyCreator'
Eagerly caching bean 'org.springframework.aop.config.internalAutoProxyCreator' to allow for resolving potential circular references
Finished creating instance of bean 'org.springframework.aop.config.internalAutoProxyCreator'
Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3224f60b: defining beans [org.springframework.aop.config.internalAutoProxyCreator,dataSource,txManager,fooDao,fooService,txAdvice,fooServiceOperation,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0]; root of factory hierarchy
Returning cached instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
Creating shared instance of singleton bean 'dataSource'
Creating instance of bean 'dataSource'
Creating shared instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Creating instance of bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Eagerly caching bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0' to allow for resolving potential circular references
Creating instance of bean 'fooServiceOperation'
Finished creating instance of bean 'fooServiceOperation'
Finished creating instance of bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Eagerly caching bean 'dataSource' to allow for resolving potential circular references
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Finished creating instance of bean 'dataSource'
Creating shared instance of singleton bean 'txManager'
Creating instance of bean 'txManager'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Eagerly caching bean 'txManager' to allow for resolving potential circular references
Returning cached instance of singleton bean 'dataSource'
Invoking afterPropertiesSet() on bean with name 'txManager'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Finished creating instance of bean 'txManager'
Creating shared instance of singleton bean 'fooDao'
Creating instance of bean 'fooDao'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Eagerly caching bean 'fooDao' to allow for resolving potential circular references
Returning cached instance of singleton bean 'txManager'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Finished creating instance of bean 'fooDao'
Creating shared instance of singleton bean 'fooService'
Creating instance of bean 'fooService'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Eagerly caching bean 'fooService' to allow for resolving potential circular references
Returning cached instance of singleton bean 'fooDao'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Creating shared instance of singleton bean 'txAdvice'
Creating instance of bean 'txAdvice'
Eagerly caching bean 'txAdvice' to allow for resolving potential circular references
Returning cached instance of singleton bean 'txManager'
Creating instance of bean '(inner bean)#63021689'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Finished creating instance of bean '(inner bean)#63021689'
Invoking afterPropertiesSet() on bean with name 'txAdvice'
Finished creating instance of bean 'txAdvice'
Finished creating instance of bean 'fooService'
Returning cached instance of singleton bean 'txAdvice'
Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
Returning cached instance of singleton bean 'lifecycleProcessor'
Returning cached instance of singleton bean 'fooService'

see this:

Application code is required to retrieve the JDBC Connection via DataSourceUtils.getConnection(DataSource) instead of a standard Java EE-style DataSource.getConnection() call. Spring classes such as JdbcTemplate use this strategy implicitly.

thansk for @JB Nizet, @SachinSarawgi.

I should use the JdbcTemplate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM