메시지 본문을 저장하고 별도의 열에서 문자열(ed) 헤더를 선택하도록 JdbcAggregationRepository 를 구성할 수 있습니다. 예를 들어 본문을 저장하고 다음 두 개의 헤더 companyName 및 accountName 은 다음 SQL을 사용합니다.
CREATE TABLE aggregationRepo3 (
id varchar(255) NOT NULL,
exchange blob NOT NULL,
version BIGINT NOT NULL,
body varchar(1000),
companyName varchar(1000),
accountName varchar(1000),
constraint aggregationRepo3_pk PRIMARY KEY (id)
);
CREATE TABLE aggregationRepo3_completed (
id varchar(255) NOT NULL,
exchange blob NOT NULL,
version BIGINT NOT NULL,
body varchar(1000),
companyName varchar(1000),
accountName varchar(1000),
constraint aggregationRepo3_completed_pk PRIMARY KEY (id)
);
CREATE TABLE aggregationRepo3 (
id varchar(255) NOT NULL,
exchange blob NOT NULL,
version BIGINT NOT NULL,
body varchar(1000),
companyName varchar(1000),
accountName varchar(1000),
constraint aggregationRepo3_pk PRIMARY KEY (id)
);
CREATE TABLE aggregationRepo3_completed (
id varchar(255) NOT NULL,
exchange blob NOT NULL,
version BIGINT NOT NULL,
body varchar(1000),
companyName varchar(1000),
accountName varchar(1000),
constraint aggregationRepo3_completed_pk PRIMARY KEY (id)
);
Copy to ClipboardCopied!Toggle word wrapToggle overflow
그런 다음 아래와 같이 이 동작을 사용하도록 리포지토리를 구성합니다.
<bean id="repo3"
class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository">
<property name="repositoryName" value="aggregationRepo3"/>
<property name="transactionManager" ref="txManager3"/>
<property name="dataSource" ref="dataSource3"/>
<!-- configure to store the message body and following headers as text in the repo -->
<property name="storeBodyAsText" value="true"/>
<property name="headersToStoreAsText">
<list>
<value>companyName</value>
<value>accountName</value>
</list>
</property>
</bean>
<bean id="repo3"
class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository">
<property name="repositoryName" value="aggregationRepo3"/>
<property name="transactionManager" ref="txManager3"/>
<property name="dataSource" ref="dataSource3"/>
<!-- configure to store the message body and following headers as text in the repo -->
<property name="storeBodyAsText" value="true"/>
<property name="headersToStoreAsText">
<list>
<value>companyName</value>
<value>accountName</value>
</list>
</property>
</bean>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
모든 유형의 페이로드를 포함할 수 있으므로 교환은 디자인별로 직렬화할 수 없습니다. 데이터베이스 BLOB 필드에 저장할 바이트 배열로 변환됩니다. 이러한 모든 변환은 JdbcCodec 클래스에서 처리합니다. 코드에 대한 한 가지 세부 사항은 ClassLoadingAwareObjectInputStream 의 주의가 필요합니다.
ClassLoadingAwareObjectInputStream 이 Apache ActiveMQ 프로젝트에서 재사용되었습니다. ObjectInputStream 을 래핑하고 현재Thread 가 아닌 ContextClassLoader 와 함께 사용합니다. 다른 번들에 의해 노출되는 클래스를 로드할 수 있다는 이점이 있습니다. 이를 통해 교환 본문과 헤더에 사용자 정의 유형 오브젝트 참조가 허용됩니다.
대상 환경에 따라 집계기에 약간의 구성이 필요할 수 있습니다. 이미 알고 있듯이 각 집계기에는 자체 리포지토리(데이터베이스에서 생성된 해당 테이블 쌍)와 데이터 소스가 있어야 합니다. 기본 lobHandler가 데이터베이스 시스템에 적용되지 않으면 lobHandler 속성을 사용하여 삽입할 수 있습니다.
여러 Camel 애플리케이션이 집계 리포지토리에 대해 동일한 데이터베이스를 공유하는 클러스터형 환경에서 optimisticLocking 을 켜고 이 JDBC 기반 집계 리포지토리를 사용할 수 있습니다. 경쟁 조건이 있는 경우 JDBC 드라이버는 JdbcAggregationRepository 가 응답할 수 있는 벤더별 예외가 발생합니다. JDBC 드라이버에서 예외가 발생한 것을 알려면 이 작업을 수행할 매퍼가 필요합니다. 따라서 org.apache.camel.processor.aggregate.jdbc.JdbcOptimisticLockingExceptionMapper 를 사용하면 필요한 경우 사용자 지정 논리를 구현할 수 있습니다. 다음과 같이 작동하는 기본 구현 org.apache.camel.processor.aggregate.jdbc.DefaultJdbcOptimisticLockingExceptionMapper 가 있습니다.
다음 검사가 완료되었습니다.
발생한 예외가 SQLException 인 경우 SQLState는 23으로 시작하는 경우 확인됩니다.
발생한 예외가 DataIntegrityViolationException인 경우
발생한 예외 클래스 이름에 "ConstraintViolation"이 이름에 있는 경우.
클래스 이름이 구성된 경우 FQN 클래스 이름에 대한 선택적 검사와 일치합니다.
또한 FQN 클래스 이름을 추가할 수 있으며 발생한 예외(또는 중첩) 중 하나라도 FQN 클래스 이름 중 하나와 같은 경우 optimistick 잠금 오류가 발생합니다.
다음은 JDBC 공급업체에서 2개의 추가 FQN 클래스 이름을 정의하는 예입니다.
<bean id="repo"
class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository">
<property name="transactionManager" ref="transactionManager"/>
<property name="repositoryName" value="aggregation"/>
<property name="dataSource" ref="dataSource"/>
<property name="jdbcOptimisticLockingExceptionMapper" ref="myExceptionMapper"/>
</bean>
<!-- use the default mapper with extraFQN class names from our JDBC driver -->
<bean id="myExceptionMapper" class="org.apache.camel.processor.aggregate.jdbc.DefaultJdbcOptimisticLockingExceptionMapper">
<property name="classNames">
<util:set>
<value>com.foo.sql.MyViolationExceptoion</value>
<value>com.foo.sql.MyOtherViolationExceptoion</value>
</util:set>
</property>
</bean>
<bean id="repo"
class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository">
<property name="transactionManager" ref="transactionManager"/>
<property name="repositoryName" value="aggregation"/>
<property name="dataSource" ref="dataSource"/>
<property name="jdbcOptimisticLockingExceptionMapper" ref="myExceptionMapper"/>
</bean>
<!-- use the default mapper with extraFQN class names from our JDBC driver -->
<bean id="myExceptionMapper" class="org.apache.camel.processor.aggregate.jdbc.DefaultJdbcOptimisticLockingExceptionMapper">
<property name="classNames">
<util:set>
<value>com.foo.sql.MyViolationExceptoion</value>
<value>com.foo.sql.MyOtherViolationExceptoion</value>
</util:set>
</property>
</bean>
Copy to ClipboardCopied!Toggle word wrapToggle overflow
JdbcAggregationRepository 는 Spring-TX의 두 가지 별도의 트랜잭션 템플릿을 사용합니다. 하나는 읽기 전용입니다.One is read-only and one is used for read-write operations.
그러나 < transacted / >를 사용하는 경로에 JdbcAggregationRepository 를 사용하고 사용되는 일반적인 PlatformTransactionManager 가 사용되는 경우 JdbcAggregationRepository 내부의 트랜잭션 템플릿에서 사용하는 전파 동작을 구성해야 할 수 있습니다.
JdbcAggregationRepository 에서 사용하는 optimistic 잠금에 문제가 발생할 수 있는 특수 데이터베이스가 있습니다. PostgreSQL은 데이터 무결성 위반 예외(SQLState 23505)를 사용하는 경우 연결이 유효하지 않은 것으로 표시됩니다. 이로 인해 중첩된 트랜잭션 내에서 연결을 효과적으로 사용할 수 없게 됩니다. 자세한 내용은 문서에서 찾을 수 있습니다.
org.apache.camel.processor.aggregate.jdbc.PostgresAggregationRepository 는 JdbcAggregationRepository 를 확장하고 특수 INSERT를 사용합니다. ON CONFLICT .. statement to provide optimistic locking behavior.
이 명령문은 (기본 집계 테이블 정의)입니다.
INSERT INTO aggregation (id, exchange) values (?, ?) ON CONFLICT DO NOTHING
INSERT INTO aggregation (id, exchange) values (?, ?) ON CONFLICT DO NOTHING
Copy to ClipboardCopied!Toggle word wrapToggle overflow
이 절을 사용하면 java.sql.PreparedStatement.executeUpdate() 호출이 SQLState=23505로 SQLException을 throw하는 대신 0 을 반환합니다. 추가 처리는 일반 JdbcAggregationRepository 와 정확히 동일하지만 PostgreSQL 연결을 유효하지 않음으로 표시하지 않습니다.