返回首页

gbase数据、南大通用产品文档:GBase8a一般J2EE 连接池概念

更新日期:2024年09月11日

连接池是创建和管理一个连接的缓冲池的技术,
这些连接准备好被任何需要它们的
线程使用。
这种把连接汇集起来的技术基于这样的一个事实:对于大多数应用程序,当它们正
在处理通常需要数毫秒完成的事务时,仅需要能够访问JDBC 连接的1 个线程。当
不处理事务时,这个连接就会闲置。相反,连接池允许闲置的连接被其它需要的线
程使用。
事实上,当一个线程需要用JDBC 对一个GBase 或其它数据库操作时,它从连接
池中请求一个连接。当这个线程使用完了这个连接,将它返回到连接池中,这样这
就可以被其它想使用它的线程使用。
当连接从池中借出,它被请求它的线程专有地使用。从编程的角度来看,这和用户
的线程每当需要一个JDBC 连接的时候调用DriverManager.getConnection()是一样
的,采用连接池技术,可通过使用新的或已有的连接结束线程。
连接池可以极大的改善用户的Java 应用程序的性能,
同时减少全部资源的使用。

接池主要的优点有:

减少连接创建时间
虽然与其它数据库相比GBase 提供了较为快速的连接功能,
但是创建新的JDBC 连
接仍会招致网络和 JDBC 驱动的开销。如果这类连接是“循环”使用的,那么使用
该方式造成的这些花销就可避免。

简化的编程模式
当使用连接池时,
每一个单独的线程能够像创建了一个自己的JDBC 连接一样操作,
允许用户直接使用JDBC 编程技术。

受控的资源使用
如果用户不使用连接池,而是每当线程需要时创建一个新的连接,那么用户的应用
程序的资源使用会产生非常大的浪费并由可能会导致高负载下的异常发生。
注意
每个连到GBase 的连接在客户端和服务器端都有花销(内存,CPU,上下文切换
等等)。每个连接均会对应用程序和GBase 服务器的可用资源带来一定的限制。不管
这些连接是否在做有用的工作,仍将使用这些资源中的相当一部分。
连接池能够使性能最大化,同时还能将资源利用控制在一定的水平之下,如果超过

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1031
该水平,应用程序将崩溃而不仅仅是变慢。
幸运的是,Sun 已经通过JDBC-2.0 可选的接口,标准化了JDBC 中的连接池的概
念,并且所有的主流应用服务基本都实现了与GBase JDBC 一起良好工作的这类
API。
通常,
你可以在应用服务器的配置文件中配置连接池,
并通过Java 命名和目录接口
(JNDI)访问它。在下面的代码中,介绍了在J2EE 应用服务器上运行的应用程序
中使用连接池的方法::

示例:在J2EE 应用服务器上使用连接池,部分代码如下:
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class GBaseServletJspOrEjb {
public void doSomething() throws Exception {
/*
* Create a JNDI Initial context to be able to lookup the
* DataSource In production-level code, this should be *cached
* as an instance or static variable, as it can be quite
* expensive to create a JNDI context.
* Note: This code only works when you are using servlets
* or EJBs in a J2EE application server. If you are
* using connection pooling in standalone Java code, you
* will have to create/configure datasources using whatever
* mechanisms your particular connection pooling library
* provides.
*/
InitialContext InitCtx = new InitialContext();
/*
* Lookup the DataSource, which will be backed by a pool
* that the application server provides. DataSource instances
* are also a good candidate for caching as an instance
* variable, as JNDI lookups can be expensive as well.
*/
DataSource ds = (DataSource) InitCtx.lookup("java:comp/env/jdbc/GBaseDB");
/*
The following code is what would actually be in your
Servlet, JSP or EJB 'service' method...where you need
to work with a JDBC connection.
*/
Connection conn = null;
Statement stmt = null;

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1032
try {
conn = ds.getConnection();
/*
Now, use normal JDBC programming to work with
GBase, making sure to close each resource when you're
finished with it, which allows the connection pool
resources to be recovered as quickly as possible
*/
stmt = conn.createStatement();
stmt.execute("DO SOME SQL QUERY");
stmt.close();
stmt = null;
conn.close();
conn = null;
} finally {
/*
* close any jdbc instances here that weren't
* explicitly closed during normal code path, so
* that we don't 'leak' resources...
*/
if (stmt != null) {
try {
stmt.close();
} catch (sqlexception sqlex) {
//ignore -- as we can't do anything about it here
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (sqlexception sqlex) {
//ignore -- as we can't do anything about it here
}
conn = null;
}
}
}
}
如上面的例子所示,
在获得JNDI InitialContext 并查找DataSource 之后,
剩下的代
码与前面完成的JDBC 编程看起来类似。

GBase UP 产品手册 6 应用开发指南
文档版本04(2021-04-21) 南大通用数据技术股份有限公司 1033
当使用连接池时,
要记住的最重要的是确保无论在用户的代码中发生了什么
(意外,
控制流等),连接和任何由它们创建的东西(语句,结果集等)都是需要关闭的,
以便于它们可以被再使用,否则的话它们会进退两难,这在最好的情况下意味着它
们代表的GBase 服务器资源(缓存,锁,套接字等)会在某时被占用,在最坏的
情况下,会被永远占用。
连接池最佳大小是多少,与其它所有配置规则一样,答案是“取决于具体情况”。
最佳的大小依赖于预期负载和平均数据库事务时间,
最适合的连接池大小比用户预
期的要小。
如果用户以Sun's Java Petstore Blueprint 应用程序进行测试,测试使用GBase 和
Tomcat。
在GBase 中设置15-20 个连接的连接池为中等规模的负载
(600 用户并发)
服务,其响应时间在可接受的范围内。
要想确定用于应用程序的连接池大小,应使用诸如Apache Jmeter 或The Grinder 等
工具创建负载测试脚本,并对应用程序进行负载测试。
一个决定在连接池中放置的合理连接数的最简单的办法是先将连接池的连接数设
置到极大,然后运行负载测试对并发用户的最大值进行检测,这样用户就可以得出
使用户指定程序得到最佳性能的连接数最大值和最小值。

支持GBase UP 的Blob Uri 字段的存取,使用时注意以下几点要求:

必须使用Prepare

必须使用Parameters

大文件必须使用FileStream 作为Parameters 的参数

Select 时必须将Blob Uri 字段放在所有字段最后

Select 时DataReader 必须使用CommandBehavior.SequentialAccess
流式读取模式

Select 时先执行GetBlobLength()获取Blob
Uri 字段值的长度,
再循
环执行GetBlob 获取
使用代码示例如下:
string connstr =
"server=192.168.8.29;database=song;uid=gbase;pwd=gbase20110531;pooling=false;
Ignore Prepare=false;";//连接参数中必须指定Ignore Prepare=false

FileStream fsin;
string filepath = @"d:\1.bmp";
string tablename = "test1";
fsin = new FileStream(filepath,FileMode.Open,FileAccess.Read);
long fsinlength = fsin.Length;
string sql = "drop table if exists " + tablename;
using (GBaseConnection conn = new GBaseConnection(connstr))
{
conn.Open();



GBase 8a 程序员手册ADO.NET 篇
南大通用数据技术股份有限公司

- 337 -
using (GBaseCommand cmd = new GBaseCommand(sql,conn))
{
cmd.ExecuteNonQuery();
cmd.CommandText = "create table " + tablename + " (a int, b blob uri, c
varchar(30))";
cmd.ExecuteNonQuery();

cmd.CommandText = "insert into " + tablename + " values(@a,@b,@c)";
cmd.CommandTimeout = 20000;
cmd.Parameters.AddWithValue("@a", 1);
cmd.Parameters.AddWithValue("@b", fsin); //将FileStream作为参数传入
cmd.Parameters.AddWithValue("@c", "song");
cmd.Prepare();//必须先Prepare
cmd.ExecuteNonQuery();
}
fsin.Close();

FileStream fsout;
string outpath = @"d:\outfile.bmp";
if (File.Exists(outpath))
{
File.Delete(outpath);
}
fsout = new FileStream(outpath, FileMode.OpenOrCreate, FileAccess.Write);

sql = "select a,c,b from " + tablename; //select时将blob uri字段放在最后
using (GBaseCommand cmd = new GBaseCommand(sql,conn))
{
cmd.Prepare();//开启prepare
cmd.CommandTimeout = 20000;//timeout设置大,防止在读取较大数据
时超时退出


GBase 8a 程序员手册ADO.NET 篇


- 338 -

南大通用数据技术股份有限公司
using (GBaseDataReader reader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess)) //必须设置为流式读取
{
while (reader.Read())
{
Assert.AreEqual(1, reader.GetValue(0));
Assert.AreEqual("song", reader.GetValue(1));
long len = 0;
len = reader.GetBlobLength(2);//读取blob uri时,先获取列值的
长度 GetBlobLength
if (len == 0)
{
Console.WriteLine("blob uri is null");
}
Assert.AreEqual(len, fsinlength);//判断获取的长度等于存入时
的长度

byte[] result = null;
long alreadyRead = 0;//已经读取的长度
while (alreadyRead < len)//循环获取值
{
result = reader.GetBlob(2, alreadyRead); //读满,一个数据
包最大16M,内存够用 GetBlob
fsout.Write(result, 0, result.Length);
alreadyRead += result.Length;
}

fsout.Close();
}
}
}
}





背景信息
gs_check 改进增强,
统一化当前系统中存在的各种检查工具,
例如gs_check、
gs_checkos
等,帮助用户在GBase 8c 运行过程中,全量的检查GBase 8c 运行环境、操作系统环境、网
络环境及数据库执行环境,也有助于在GBase 8c 重大操作之前对各类环境进行全面检查,
有效保证操作执行成功。
注意事项

必须指定-i 或-e 参数,-i 会检查指定的单项,-e 会检查对应场景配置中的多项。

GBase 8c 工具参考手册
南大通用数据技术股份有限公司
71

如果-i 参数中不包含root 类检查项或-e 场景配置列表中没有root 类检查项,则不需要
交互输入root 权限的用户及其密码。

可使用--skip-root-items 跳过检查项中包含的root 类检查,以免需要输入root 权限用户
及密码。

MTU 值不一致时可能导致检查缓慢或进程停止响应,当巡检工具出现提示时请修改各
节点MTU 值一致后再进行巡检。

交换机不支持当前设置的MTU 值时,即使MTU 值一致也会出现通信问题引起进程停
止响应,需要根据交换机调整MTU 大小。