对于到达REST api的每个请求,我必须对数据库实施一次数据访问(CRUD调用)。什么是使其成为线程安全实现的最佳方法。 目前,对于REST api,我有一个请求。我可以将它添加到队列中。并返回。我可以创建一个从队列中轮询的消费者线程。 但是,我将非常感谢有关如何使用消费者线程对请求进行数据库访问的任何见解,这是线程安全的。我使用spring进行DAO访问。这是我的DAO课程。
package dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Service;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.mysql.jdbc.PreparedStatement;
public class UserDAOImpl extends JdbcDaoSupport implements UserDAO
{
@Autowired
private DriverManagerDataSource datasource;
private void setDataSource(DriverManagerDataSource datasource)
{
this.datasource = datasource;
}
@Override
public List<User> getUsers(String userid) {
//String query;
String database_name="tennis.";
String sql = " select distinct ux.id as user_id , ux.first_name, ux.last_name , lvl.rating as rating , photo.filename as file_name"+
" from mytable.user as ux, "+database_name+"profile as pf , "+database_name+"level as lvl, mytable.photo as photo "+
" where "+
" ux.id = pf.user_id "+
" and ux.id = photo.user_id"+
" and pf.level_id = lvl.id"+
" and ux.id in "+
" ( select distinct user_id from "+database_name+"profile "+
" where "+database_name+"profile.level_id in "+
" (select l.id as levelid "+
" from "+database_name+"level as l "+
" where l.rating between "+
" ( ( select distinct level.rating "+
" from "+database_name+"level, "+database_name+"profile "+
" where level.id = profile.level_id and profile.user_id = ?) -?) "+
" and "+
" ( ( select distinct level.rating "+
" from "+database_name+"level, "+database_name+"profile "+
" where level.id = profile.level_id "+
" and profile.user_id = ?)+?) )) ";
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);
}
};
List<User> users = getJdbcTemplate().query(sql,ps2,new RowMapper<User>()
{
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException
{
User user = new User();
user.setUserid(rs.getString(1));
user.setFirstName(rs.getString(2));
user.setLastName(rs.getString(3));
user.setRating( rs.getString(4));
//user.setPhoto_file_path(rs.getString(5));
return user;
}});
System.out.println(users.size());
// for(User user: users)
// System.out.println(user);
return users;
}
}
答案 0 :(得分:0)
目前尚不清楚您对线程安全的具体关注是什么,但如果一个对象没有状态,那么根据定义,它是线程安全的。
我在上面包含的dao实现中可以看到的唯一状态是注入数据源,只要在spring中在线程级别正确管理事务和连接,数据源本身应该是线程安全的。
如果没有,你可以通过定义ProviderCreatingFactoryBean使你的dao原型作用域并使用java.inject.Provider注入它。然而,这会产生一些性能影响。