2016-01-19 7 views
1

Мы в процессе изменения некоторых приложений, использующих базу данных отношений, для OrientDB (2.1.9). Эта транзакция будет выполнена небольшими шагами, и мы сначала начнем с подхода JDBC-драйверов, и, возможно, позже мы переключимся на собственную реализацию.OrientDB - Драйвер JDBC, управляемый пулом подключений

У нас есть приложение, основанное на Spring Integration, где мы изменили с Oracle Database на OrientDB, используя драйвер JDBC.

соединения с базой данных управляется Tomcat 8 пул соединений, и транзакционное поведение обрабатывается диспетчером транзакций в Spring:

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> 
    <property name="driverClassName" value="com.orientechnologies.orient.jdbc.OrientJdbcDriver" /> 
      ... 
</bean>    

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
      <property name="dataSource" ref="dataSource" /> 
</bean> 

После изменения базы данных в OrientDB, мы столкнулись следующее сообщение об ошибке:

com.orientechnologies.orient.core.exception.ODatabaseException: Database instance is not set in current thread. Assure to set it with: ODatabaseRecordThreadLocal.INSTANCE.set(db);

OrientDB документация, на многопоточность, говорится:

OrientDB supports multi-threads access to the database. ODatabase* and OrientGraph* instances are not thread-safe, so you've to get an instance per thread and each database instance can be used only in one thread per time. For more information about how concurrency is managed by OrientDB look at Concurrency.

Since v2.1 OrientDB doesn't allow implicit usage of multiple database instances from the same thread. Any attempt to manage multiple instances in the same thread must explicitly call the method db.activateOnCurrentThread() against the database instance BFORE you use it.

Это создает проблему, так как все управление подключением к базе данных обрабатывается пулом подключений (как и должно быть). Итак, для реализации решения, предлагаемого OrientDB, мне пришлось иметь доступ к базе данных ODatabaseDocumentTx, чтобы применить метод activateOnCurrentThread().

Чтобы это сделать, мне пришлось создать оболочку как из класса драйвера JDBC, так и из интерфейса OrientJdbcConnection.

В OrientJdbcConnection я получил основную базу данных с помощью Java Reflection:

public class OrientJdbcConnectionWrapper extends OrientJdbcConnection { 

    @Override 
    public void commit() throws SQLException { 

    final ODatabaseDocumentTx database = getPrivateDatabaseFieldByReflection(); 

    database.activateOnCurrentThread(); 

    super.commit(); 
} 

и класса Driver обертки JDBC, теперь возвращает обернутое соединение: общественного класс OrientJdbcDriverWrapper расширяет OrientJdbcDriver {

public Connection connect(final String url, final Properties info) throws SQLException { 
     if (!acceptsURL(url)) { 
      throw new SQLException(DO_NOT_ACCEPT_URL_ERROR + url); 
     } 

     return new OrientJdbcConnectionWrapper(url, info); 
    } 

}

Наконец, конфигурация пула подключений теперь использует завернутые водитель:

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> 
    <property name="driverClassName" value="x.y.z.driver.orientdb.OrientJdbcDriverWrapper" /> 
</bean> 

Как и ожидалось, это работает отлично, но я не совсем уверен, что это правильный способ сделать это, как я не видел никого с этим вопросом.

С другой стороны, документация OrientDB предлагает использовать activOnCurrentThread() в многопоточной среде.

ответ

0

OrientDB имеет свой собственный пул базы данных, которые могут быть легко сконфигурированы:

<bean id="dataSource" class="com.orientechnologies.orient.jdbc.OrientDataSource"> 
    <constructor-arg name="url" value="jdbc:orient:plocal:xx\\databases\\test" /> 
    <constructor-arg name="username" value="xx"/> 
    <constructor-arg name="password" value="xx"/> 
    <constructor-arg name="info" ref="databaseProperties" />   
</bean> 


<util:map id="databaseProperties" value-type="java.lang.String"> 
    <entry key="db.usePool" value="true" /> 
    <entry key="db.pool.min" value="1" /> 
    <entry key="db.pool.max" value="10" />  

Примечание: Я использую OrientDB через Orient-драйвер JDBC.

Смежные вопросы