Android中的数据库连接池

《Android中的数据库连接池》
最近在看数据库相关的三方库的时候,我发现在Android应用开发的时候是可以并行操作数据库的读写,但Android默认的数据连接池中只有一个数据库链接。一个数据库连接能实现并发么?要是一个数据库链接可以实现并发,那么为什么需要数据库连接池?

数据库连接池介绍

每次提到连接池我们很快能想到线程池。线程池的创建可以减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

数据库连接是一种关键的有限的昂贵的资源,对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,减少链接不断传销和销毁带来的资源浪费。

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:

  1. 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。

  2. 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作

  3. 如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放。

Android数据库相关类介绍

  • SQLiteOpenHelper:管理SQLite的帮助类,提供获取SQLIteDatabase实例的方法,它会在第一次使用数据库时调用获取实例方法时创建SQLiteDatabase实例,并且处理数据库版本变化,开发人员在实现ContentProvider时都要实现一个自定义的SQLiteOpenHelper类,处理数据的创建、升级和降级。
  • SQLiteDatabase:代表一个打开的SQLite数据库,提供了执行数据库操作的接口方法。如果不需要在进程之间共享数据,应用程序也可以自行创建这个类的实例来读写SQLite数据库。
  • SQLiteSession:SQLiteSession负责管理数据库连接和事务的生命周期,通过SQLiteConnectionPool获取数据库连接来执行具体的数据库操作。
  • SQLiteConnectionPool:数据库连接池,管理所有打开的数据库连接(Connection)。所有数据库连接都是通过它来打开,打开后会加入连接池,在读写数据库时需要从连接池中获取一个数据库连接来使用。
  • SQLiteConnection:代表了数据库连接,每个Connection封装了一个native层的sqlite3实例,通过JNI调用SQLite动态库的接口方法操作数据库,Connection要么被Session持有,要么被连接池持有。
  • CursorFactory:可选的Cursor工厂,可以提供自定义工厂来创建Cursor。
  • DatabaseErrorHandler:可选的数据库异常处理器(目前仅处理数据库Corruption),如果不提供,将会使用默认的异常处理器。
  • SQLiteDatabaseConfiguration:数据库配置,应用程序可以创建多个到SQLite数据库的连接,这个类用来保证每个连接的配置都是相同的。
  • SQLiteQuery和SQLiteStatement:从抽象类SQLiteProgram派生,封装了SQL语句的执行过程,在执行时自动组装待执行的SQL语句,并调用SQLiteSession来执行数据库操作。这两个类的实现应用了设计模式中的命令模式。

每个类的更加详细的介绍可以阅读 SQLite数据库学习小结**——Frameworks**层实现 这篇文章,我们这里主要学习 SQLiteConnectionPool 相关的知识。

SQLiteConnectionPool

数据库连接池我们先看一下它的大小,每个链接的获取以及其他功能?

连接池大小

目前Android系统的实现中,如果以非WAL模式打开数据库,连接池中只会保持一个数据库连接,如果以WAL模式打开数据库,连接池中的最大连接数量则根据系统配置决定,默认配置是两个。

//SQLiteConnectionPool.java
private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
//数据库的配置信息
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
//设置最大的数据库链接个数
setMaxConnectionPoolSizeLocked();
//超时处理句柄设置,如果超时时间为MAX_VALUE,那么链接永远不关闭
// If timeout is set, setup idle connection handler
// In case of MAX_VALUE - idle connections are never closed
if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
setupIdleConnectionHandler(Looper.getMainLooper%2

点赞