如何为多个用户制作DAO实现规模

时间:2015-05-18 23:24:39

标签: multithreading concurrency jdbctemplate

我手头有问题,我用spring实现了DAO。其中提取用户对象列表。

我实现了一个callable,它作为任务传递给ExecutorService。 call()命中数据库以获取用户实体列表。

现在我担心的是:当在ExecutorService线程池中安排此任务时,多个线程同时命中数据库。因此,在20个并发运行的线程之后,我得到了太多与数据库异常的连接。

代码如下:

private class ConsumeCallable implements Callable<WrapperResponse<EntityInterface>> {
        private final String userid;
        private int minimumRange, maxRange;

        // private final AsyncResponse asyncresponse;
        private ConsumeCallable(final String entity,  int minimumRange, int maxRange) {
            this.maxRange = minimumRange;
            this.maxRange = maxRange;
            this.userid = entity;
        }

        /**  we need to have the parameters set in the task, so creating a wrapper 
         * */
        ConsumeCallable(final String userid, int minimumRange, int maxRange){
            this(userid, minimumRange, maxRange);
            this.asyncresponse = asyncresponse;
        }

        /* the wrapper response is set and returned in callable, which is used when we execute the futures*/
        @Override
        public WrapperResponse<EntityInterface> call() throws Exception 
        {
            List<EntityInterface> listOfEntities =  userdao.getUsers(userid, minimumRange, maxRange) ;
            return new WrapperResponse (userid, listOfEntities);

        }

    }

我的DAO类实现如下:

 public interface UserDAO {

          List<EntityInterface> getUsers(String userid, int minimum, int maximum);
        }



public class UserDAOImpl extends JdbcDaoSupport implements UserDAO 
{


    @Autowired
   private DriverManagerDataSource datasource;

      @Autowired 
     private JdbcTemplate jdbcTemplate;

/** here the datasource is autowired from the spring.xml file
 * The getUsers() returns a list of other users, however, this will change on future logic
 * */   
private void setDataSource(DriverManagerDataSource datasource)
    {
        this.datasource = datasource;
    }

    @Override
      public List<EntityInterface> getUsers(String userid, int  minimumRating, int maximumRating) {
        if(minimumRating<0 || maximumRating<0 )
            throw new ServiceException(new IllegalArgumentException("minimum rating and maximum rating for a user cannot be negative"));
        //String query;
        String sql = "my sql query";

        PreparedStatementSetter ps2 = new PreparedStatementSetter() {
        @Override   
        public void setValues(java.sql.PreparedStatement ps) throws SQLException {
            ps.setString(1, userid);
            ps.setInt(2, 1);
            ps.setString(3, userid);
            ps.setInt(4, 1);
            //System.out.println(ps.toString());
        }

        };


        List<EntityInterface> users = this.getJdbcTemplate().query(sql,ps2,new RowMapper<EntityInterface>()
       {

              @Override
              public User mapRow(ResultSet rs, int rowNum) throws SQLException 
              {

                User user = new User();

               // populate user objects using the user.setter(rs.getString(i));
               // return user;
              }});

        if(users == null) 
            users = new ArrayList<EntityInterface>();

        return users;

      }

}

spring.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:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">


    <context:component-scan base-package="dao"/>
    <context:component-scan base-package="com.crudapp"/>
    <!-- Enable Annotation based Declarative Transaction Management -->
    <tx:annotation-driven proxy-target-class="true"
        transaction-manager="transactionManager" />

    <!-- Creating TransactionManager Bean, since JDBC we are creating of type 
        DataSourceTransactionManager -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- MySQL DB DataSource -->
    <bean id="dataSource"  class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="url_string" />
        <property name="username" value="username" />
        <property name="password" value="password" />
    </bean>

    <bean id="userDAO" class="crudapproot.dao.UserDAOImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
    </bean>

</beans>

1 个答案:

答案 0 :(得分:0)

您可能需要考虑使用连接池,请参阅this blog post以获取示例 - 这样您就可以将xml配置为永远不会创建比数据库可支持的连接更多的连接。