是否应该为每个rest调用打开JDBC连接?

时间:2019-01-18 17:38:11

标签: java jdbc

我在Spring Boot项目中处理高流量,我的目标是尽可能快地为客户提供服务。在这种情况下,我每秒有500个以上的请求。在每个其余端点调用中,我应该连接我的架构并从多个表中收集多个信息。为此,我应该为每个eendpoint调用创建新连接还是在每个数据库查询之前创建并关闭?

我写了一个JDBC连接类,但是我不确定这是一个好方法。也许你可以给我一些意见。

JDBC连接类

@PropertySource({"classpath:application.properties"})
@Configuration
public class FraudJDBConfiguration {
    private final Logger LOGGER = LogManager.getLogger(FraudJDBConfiguration.class);

    private final Environment env;

    @Autowired
    public FraudJDBConfiguration(Environment env) {
        this.env = env;
    }

    @Bean
    public Connection getFraudConnection() {
        // Step 1: Loading or
        // registering Oracle JDBC driver class
        String connectionClass = env.getProperty("fraud.db.driver-class-name");
        try {
            Class.forName(connectionClass);
        } catch (ClassNotFoundException cnfex) {
            LOGGER.error(cnfex.getMessage());
            throw new RuntimeException("JDBC driver class'ı bulunamadı");
        }

        // Step 2: Opening database connection
        try {
            String environmentType = env.getProperty("environment");
            if (environmentType == null) {
                LOGGER.error("environment Tip Hatası (TEST - UAT - LIVE)");
                throw new RuntimeException("environment Tip Hatası (TEST - UAT - LIVE)");
            } else {
                String connectionString = null;
                String username = null;
                String password = null;
                switch (environmentType.toLowerCase()) {
                    case "dev":
                        connectionString = env.getProperty(/*someurl*/);
                        username = env.getProperty(/*someusername*/);
                        password = env.getProperty(/*somepassword*/);
                        break;
                    case "tst":
                        connectionString = env.getProperty(/*someurl*/);
                        username = env.getProperty(/*someusername*/);
                        password = env.getProperty(/*somepassword*/);
                        break;
                    case "liv":
                        connectionString = env.getProperty(/*someurl*/);
                        username = env.getProperty(/*someusername*/);
                        password = env.getProperty(/*somepassword*/);
                        break;
                    case "uat":
                        connectionString = env.getProperty(/*someurl*/);
                        username = env.getProperty(/*someusername*/);
                        password = env.getProperty(/*somepassword*/);
                        break;
                }
                // Step 2.A: Create and
                // get connection using DriverManager class
                if (connectionString == null) {
                    LOGGER.error("fraud şeması için connection string bulunamadı");
                    throw new RuntimeException("fraud şeması için connection string bulunamadı");
                }
                return DriverManager.getConnection(connectionString, username, password);
            }
        } catch (SQLException e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }
}

DAO

@Component
public interface FraudCommTransactionsDao {
    Long count();
}

DAO IMPL

@Service
public class FraudCommTransactionsDaoImpl implements FraudCommTransactionsDao {
    private final FraudJDBConfiguration fraudJDBConfiguration;

    @Autowired
    public FraudCommTransactionsDaoImpl(FraudJDBConfiguration fraudJDBConfiguration) {
        this.fraudJDBConfiguration = fraudJDBConfiguration;
    }

    @Override
    public Long count() {
        try(Connection connection = fraudJDBConfiguration.getFraudConnection()) {
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery(/*some query*/);

            if (rs.next()) {
                return rs.getLong("transaction_id");
            } else {
                return 0L;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
        return null;
    }
}

2 个答案:

答案 0 :(得分:0)

否,与数据库服务器建立新的物理连接非常昂贵。它涉及多个步骤:用户授权,建立会话默认值,在客户端和服务器上分配内存等。不应将此开销添加到每个单个请求中。

创建connection pool来共享应用程序线程之间的物理连接是一种常见的做法。这引入了逻辑连接的概念,例如用Connection创建的DriverManager.getConnection()对象是物理连接,而DataSource.getConnection()返回的逻辑连接是代理。

您可以使用多个用于Java的数据库连接池库。 HikariCP。不要自己写,这是not simple

答案 1 :(得分:-1)

Get fast data and deliver to client could be possible using the simplest way of using application.properties file. You may use this to get database connection to your datasource.