TimesTenのトリガー(XLAアプリケーション)

TimesTenはPL / SQL(プロシージャ、関数、パッケージなど)をサポートしていますが、トリガーはサポートされていません。 トリガーはパフォーマンスに悪影響を及ぼします。 しかし、トリガーロジックを実装する必要がある場合はどうでしょうか。



答えは、XLAアプリケーションを作成することです。 誰でも、CまたはJavaで書くことができます。

以下では、javaを使用した例を説明します:)







Java開発者ガイドによると:



「TimesTen JMS / XLA API(JMS / XLA)を使用して、TimesTenを監視できます。

ローカルデータストア内の指定されたテーブルを変更し、これらの変更のリアルタイム通知を受け取ります。 JMS / XLAの目的の1つは、トリガーに代わる高性能で非同期の代替手段を提供することです。



つまり JMS / XLA APIを使用してTimesTenの変更に関するメッセージを(非同期モードで)受信できるJavaアプリケーションを作成できます。 JMS / XLAは、JMSパブリッシュ/サブスクライブインターフェイスを使用して、XLAの変更にアクセスします。 JMSの詳細については、こちら(http://download.oracle.com/javaee/1.3/jms/tutorial)を参照してください。



次に、そのようなアプリケーションを作成してみてください。



最初に、TimesTenでオブジェクトを作成します。

[oracle @ tt1 xla] $ ttisql dbxla



著作権1996-2010、Oracle。 無断複写・転載を禁じます。

タイプ? またはヘルプを表示するには「help」、「exit」と入力してttIsqlを終了します。



connect "DSN=dbxla"; Connection successful: DSN=dbxla;UID=oracle;DataStore=/u01/app/oracle/datastore/dbxla;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so;PermSize=32;TempSize=50;TypeMode=0;PLSQL=0;CacheGridEnable=0; (Default setting AutoCommit=1) Command> CREATE USER oratt IDENTIFIED BY oracle; User created. Command> grant create session, create table, XLA to oratt; Command> connect "DSN=dbxla;UID=oratt;PWD=oracle;"; Connection successful: DSN=dbxla;UID=oratt;DataStore=/u01/app/oracle/datastore/dbxla;DatabaseCharacterSet=WE8MSWIN1252;ConnectionCharacterSet=US7ASCII;DRIVER=/u01/app/oracle/product/11.2.1/TimesTen/tt1/lib/libtten.so;PermSize=32;TempSize=50;TypeMode=0;PLSQL=0;CacheGridEnable=0; (Default setting AutoCommit=1) con1: Command> create table xlatest ( id NUMBER NOT NULL PRIMARY KEY, > name VARCHAR2(100) ); con1: Command>
      
      







次に、ブックマークを作成します。 XLAブックマークは、トランザクションログの読み取り位置をマークするために使用されます。 この箇条書きブックマークを使用して、xlatestテーブルの変更を追跡します。

con1:Command> call ttXlaBookmarkCreate( 'bookmark');

con1:コマンド>



次に、観察するテーブルの変更を決定します。 これを行うには、ttXlaSubscribeプロシージャを呼び出します。 この場合、ブックマークブックマークを使用してxlatestテーブルの変更を観察します。

con1:Command> call ttXlaSubscribe( 'xlatest'、 'bookmark');

con1:コマンド>



次に、アプリケーションのセットアップに進みましょう。

XLAに接続するには、特定のTimesTenデータベースに関連付けられているJMSトピックに接続する必要があります。 JMS / XLA構成ファイルは、トピック名とデータベース間のバインディングを提供します。 デフォルトでは、アプリケーションは現在のディレクトリでjmsxla.xmlという特定のファイルを検索しますが、必要に応じて、このファイルの別の名前と場所を決定できます(ドキュメントを参照)。



この場合、次のjmsxla.xmlファイルを使用します。

 <xlaconfig> <topics> <!-- topic for Xla demo --> <topic name="xlademo" connectionString="DSN=dbxla" xlaPrefetch="100" /> </topics> </xlaconfig>
      
      







ご覧のとおり、xlademoトピックの名前をdbxlaデータベースにリンクしました。



それでは、Javaアプリケーションを直接作成しましょう。

最初に、コンテキストを初期化します。

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY、 "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");

InitialContext ic = new InitialContext(env);



次に、JMS接続ファクトリーを使用してXLAに接続します。 その後、接続でstart()メソッドを呼び出して、メッセージの送信を有効にします。 その後、この接続を使用してセッションを作成します。

プライベートjavax.jms.TopicConnection接続。 / ** JMS接続* /

プライベートTopicSessionセッション。 / ** JMSセッション* /

...

TopicConnectionFactory connectionFactory =(TopicConnectionFactory)ic.lookup( "TopicConnectionFactory");

connection = connectionFactory.createTopicConnection();

...

//セッションを取得します

session = connection.createTopicSession(false、Session.AUTO_ACKNOWLEDGE);

...



また、セッションを作成するときは、セッションのトランザクションの性質と確認応答モードのタイプを指定する必要があります。

JMS / XLAは3つのモデル(AUTO_ACKNOWLEDGE、DUPS_OK_ACKNOWLEDGE、CLIENT_ACKNOWLEDGE)をサポートしています。モデルの詳細については、ドキュメントをご覧ください。 この例では、最初のモデルを使用し、セッションのトランザクション性をfalseに設定します。



次に、メッセージの受信モードを決定する必要があります。 同期と非同期の2つのオプションが可能です。



同期バージョンでは、メッセージは順番に処理されます(順番に処理されます)。 これは、メッセージが処理されていない間、別のものが待機していることを意味します。

同期バリアントの場合、接続でstart()メソッドを呼び出して、メッセージの送信をアクティブにし、トピックを作成してから、サブスクライバーを作成し、receive()およびreceiveNoWait()メソッドを使用してメッセージを受信します。



 connection.start(); Topic topic = session.createTopic(topicName); TopicSubscriber subscriber = session.createDurableSubscriber(topic, bookmark); .. MapMessage message = (MapMessage)subscriber.receive(); ...
      
      







非同期モードでは、リスナーを作成してメッセージを処理する必要があります。

MyListener myListener = new MyListener(outStream);



トピックxlaTopic = session.createTopic(トピック);

TopicSubscriber subscriber = session.createDurableSubscriber(xlaTopic、bookmark);

...

subscriber.setMessageListener(myListener);

connection.start();

...



以下は、同期モード(ファイルDemoXLA.java)を実装するクラスの例です。

import java.util.Enumeration;

import java.util.Hashtable;

import javax.jms.JMSException;

import javax.jms.MapMessage;

import javax.jms.Session;

import javax.jms.Topic;

import javax.jms.TopicConnectionFactory;

import javax.jms.TopicConnection;

import javax.jms.TopicSession;

import javax.jms.TopicSubscriber;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;



 public class DemoXLA { private TopicConnectionFactory connectionFactory; private TopicConnection connection; private TopicSession session; private Topic topic; private TopicSubscriber subscriber; public DemoXLA( String cf, String topicName, String selector) throws JMSException, NamingException {String key; Context messaging = getInitialContext(); // getting the context connectionFactory = (TopicConnectionFactory)messaging.lookup(cf); connection = connectionFactory.createTopicConnection(); connection.start(); session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); subscriber = session.createDurableSubscriber(topic, selector); int i=0; while (i<10) { MapMessage message = (MapMessage)subscriber.receive(); Enumeration e = message.getMapNames(); while (e.hasMoreElements()) { key = (String)e.nextElement(); System.out.println("[ " + key + " = " + message.getObject(key) + " ]"); } System.out.println("----------------------------------------"); } session.unsubscribe(selector); subscriber.close(); session.close(); connection.stop(); } private Context getInitialContext() throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory"); InitialContext initialContext = new InitialContext(env); return initialContext; } public static void main(String[] args) throws JMSException, NamingException { DemoXLA demo = new DemoXLA("TopicConnectionFactory", "Level2Demo", "bookmark"); } }
      
      







以下は、非同期モード(MyListener.java、DemoXLA2.java)を実装するクラスの例です。



Mylistener.java

import java.util.Enumeration;

import javax.jms.JMSException;

import javax.jms.MapMessage;

import javax.jms.Message;

import javax.jms.MessageListener;



 public class MyListener implements MessageListener { public MyListener() {} public void onMessage(Message message) { MapMessage mp = (MapMessage)message; Enumeration e; try { e = mp.getMapNames(); } catch (JMSException s) { e = null; System.out.println("error 1"); } while (e.hasMoreElements()) { String key = (String)e.nextElement(); try { System.out.println("[ " + key + " = " + mp.getObject(key) + " ]"); } catch (JMSException f) { System.out.println("error 2"); } } System.out.println("----------------------------------------"); } }
      
      







DemoXLA2.java

import java.util.Hashtable;

import javax.jms.JMSException;

import javax.jms.Session;

import javax.jms.Topic;

import javax.jms.TopicConnectionFactory;

import javax.jms.TopicSession;

import javax.jms.TopicSubscriber;

import javax.naming.Context;

import javax.naming.InitialContext;

import javax.naming.NamingException;



 public class DemoXLA2 { private javax.jms.TopicConnectionFactory connectionFactory; private javax.jms.TopicConnection connection; private TopicSession session; private Topic topic; private TopicSubscriber subscriber; public DemoXLA2( String cf, String topicName, String selector) throws JMSException, NamingException, InterruptedException { Context messaging = getInitialContext(); Object connectionFactoryObject = messaging.lookup(cf); connectionFactory = (TopicConnectionFactory)connectionFactoryObject; connection = connectionFactory.createTopicConnection(); MyListener myListener = new MyListener(); session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topic = session.createTopic(topicName); subscriber = session.createDurableSubscriber(topic, selector); subscriber.setMessageListener(myListener); connection.start(); Thread.sleep(60000); session.unsubscribe(selector); subscriber.close(); session.close(); connection.stop(); } private Context getInitialContext() throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory"); InitialContext initialContext = new InitialContext(env); return initialContext; } public static void main(String[] args) throws JMSException, NamingException, InterruptedException { DemoXLA2 demo = new DemoXLA2("TopicConnectionFactory", "xlademo", "bookmark"); } }
      
      





次に、いずれかの例を実行し、xlatestテーブルのデータの作成、変更、削除を試みます。



 Command> insert into xlatest values (2, 'w'); 1 row inserted. Command> update xlatest set name = 'test' where id=2; 1 row updated. Command> delete from xlatest; 1 row deleted. Command>
      
      





したがって、アプリケーションでは次のようになります。



 [ __TYPE = 10 ] [ __COMMIT = true ] [ __FIRST = true ] [ __NULLS = ] [ __TBLNAME = XLATEST ] [ __TBLOWNER = ORATT ] [ __mver = 5621355056449191939 ] [ __mtyp = null ] [ ID = 2 ] [ NAME = w ] ---------------------------------------- [ __TYPE = 11 ] [ __COMMIT = true ] [ __FIRST = true ] [ __UPDCOLS = NAME ] [ __NULLS = ] [ __TBLNAME = XLATEST ] [ __TBLOWNER = ORATT ] [ __mver = 5621355056449191942 ] [ __mtyp = null ] [ _ID = 2 ] [ ID = 2 ] [ _NAME = w ] [ NAME = test ] ---------------------------------------- [ __TYPE = 12 ] [ __COMMIT = true ] [ __FIRST = true ] [ __NULLS = ] [ __TBLNAME = XLATEST ] [ __TBLOWNER = ORATT ] [ __mver = 5621355056449191945 ] [ __mtyp = D ] [ ID = 2 ] [ NAME = test ] ----------------------------------------
      
      







ご覧のとおり、xlatestテーブルを使用した操作に関するメッセージを受け取りました。

メッセージの形式は次のとおりです。

システム属性は、二重アンダースコアで始まります。次に例を示します。

__TYPE-操作の種類(挿入(10)、更新(11)、削除(12))も可能です(ドキュメントを参照)。 操作のタイプを決定する定数があります。

__COMMIT-トランザクションの完了を通知します(trueの場合)。

__FIRST-トランザクションの最初の操作を通知します(trueの場合)。

__TBLNAME-テーブル名

__TBLOWNER-テーブルの所有者

__NULLS-NULL値を含む属性を通知します

__mverおよび__mtypはシステム属性です。

など (ドキュメントを参照)

アンダースコアなしの属性-特定の値を持つテーブル列、たとえば:

[ID = 2]

[NAME =テスト]

1つのアンダースコアで始まる属性-古いフィールド値(更新操作中に表示されます)。例:

[_ID = 2]

[ID = 2]

[_NAME = w]

[NAME =テスト]



まとめ

したがって、Javaのかなり表面的な知識を持っている場合、TimesTenから受信した様々なメッセージを処理できるXLAアプリケーションを作成できます。 さらに、XLAアプリケーションは非同期モードで実行されますが、これはOracle TimesTenのパフォーマンスにはほとんど影響しません。



記事の著者:Gennady Sigalaev



All Articles