Spring Jersey交易问题

时间:2014-08-07 01:58:44

标签: spring transactions jersey spring-transactions jersey-2.0

我正在尝试构建Jersey + Spring Web服务应用程序。除交易管理外,一切正常。在我的UserManagerImpl.insertUserAndFailTransation中,我抛出一个异常,但用户记录仍然插入到数据库中。

可以在https://github.com/zhangyongjiang/jersey-spring-test

找到代码

的pom.xml

<...>    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jersey-version>2.6</jersey-version>
        <spring.version>4.0.6.RELEASE</spring.version>
        <servlet-api-version>3.0.1</servlet-api-version>
    </properties>
<...>    
        <dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-spring3</artifactId>
            <version>${jersey-version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey-version}</version>
        </dependency>

        <!-- Spring dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

    </dependencies>

</project>

的web.xml

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <module-name>helloworld-spring</module-name>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>SpringApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.test.MyDemoApplication</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.test</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringApplication</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

</web-app>

弹簧context.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:sec="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
   http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
   http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan
        base-package="com.test.resources;com.test.domain;com.test.storage" />

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/spring_jersey" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

TestResource.java

package com.test.resources;

import java.security.SecureRandom;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.test.domain.User;
import com.test.domain.interfaces.UserManager;

@Component
@Path("/")
public class TestResource {

    @Autowired
    private UserManager userManager;

    @GET
    @Produces("text/html")
    public String getIt() {
        User user = new User();
        user.setId(new SecureRandom().nextInt());
        user.setName("test");
        user.setUsername("username");

        this.userManager.insertUserAndFailTransation(user);
        return "uups";
    }

    @GET
    @Path("/test")
    @Produces("text/html")
    public String test() {
        User user = new User();
        user.setId(new SecureRandom().nextInt());
        user.setName("test");
        user.setUsername("username");

        this.userManager.insertUser(user);
        return "test";
    }

}

UserManagerImpl.java

package com.test.domain;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.test.domain.interfaces.UserManager;
import com.test.storage.interfaces.UserDao;

@Service
@Transactional
public class UserManagerImpl implements UserManager {

    @Autowired
    private UserDao userDAO;

    @Override
    public void insertUser(User user) {
        this.userDAO.insertUser(user);
    }

    @Override
    public void insertUserAndFailTransation(User user) {
        this.userDAO.insertUser(user);
        throw new UnsupportedOperationException();
    }

    @Override
    public User getUser(String username) {
        return this.userDAO.getUser(username);
    }

    @Override
    public List<User> getUsers() {
        return this.userDAO.getUsers();
    }
}

UserDaoImpl.java

package com.test.storage;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import com.test.domain.User;
import com.test.storage.interfaces.UserDao;

@Repository
public class UserDaoImpl extends JdbcDaoSupport implements UserDao {

    @Autowired
    public UserDaoImpl(DataSource dataSource) {
        this.setDataSource(dataSource);
    }

    @Override
    public void insertUser(User user) {
        this.getJdbcTemplate().update(
                "INSERT INTO USERS (ID, USERNAME, NAME) VALUES (?, ?, ?)",
                new Object[] {
                        user.getId(),
                        user.getUsername(),
                        user.getName()
                }
                );
    }

    @Override
    public User getUser(String username) {
        User user = this.getJdbcTemplate().
                queryForObject(
                        "SELECT * FROM USERS WHERE USERNAME = ?",
                        new Object[] { username },
                        new UserMapper()
                        );
        return user;
    }

    @Override
    public List<User> getUsers() {
        List<User> users = this.getJdbcTemplate().
                query("SELECT * FROM USERS",
                        new UserMapper()
                        );
        return users;
    }

    private class UserMapper implements RowMapper<User>{

        @Override
        public User mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            User user = new User();
            user.setId(rs.getInt("ID"));
            user.setUsername(rs.getString("USERNAME"));
            user.setName(rs.getString("NAME"));
            return user;
        }

    }

}

1 个答案:

答案 0 :(得分:0)

事实证明我需要使用MySQL innodb表进行交易。 myisam不支持交易。