-
Notifications
You must be signed in to change notification settings - Fork 0
EN Writes and Errors
TsGate 2.1.0: This guide uses
com.alandevise.tsgate.*. Upgrading from 2.0.0 requires updating imports, reflection names and package scanning, then recompiling. Central 2.0.0 retainscom.alandevise.tsdb.*. See migration steps and release status.
import com.alandevise.tsgate.annotation.TGField;
import com.alandevise.tsgate.annotation.TGMeasurement;
import com.alandevise.tsgate.annotation.TGTag;
import com.alandevise.tsgate.annotation.TGTime;
@TGMeasurement("ACCRUE")
public class AccrueRecord {
@TGTime
private Long timestamp;
@TGTag("device_code")
private String deviceCode;
@TGTag("point_type")
private String pointType;
@TGTag("source")
private String source;
@TGField("value")
private Double value;
@TGField("status")
private Long status;
}Annotations:
-
@TGMeasurement: target measurement/table. -
@TGTime: time field, restricted to non-nullLong/longvalues representing Unix Epoch milliseconds, without implicit timezone conversion. -
@TGTag: tag field, converted to a string on write. -
@TGField: ordinary field; at least one non-null field value is required.
A write POJO must declare one @TGTime and at least one @TGField. Query result objects need not be write POJOs and may omit TsGate annotations.
Inject com.alandevise.tsgate.core.TGTemplate. When a backend is active, its starter registers the shared template under the default bean name tgTemplate:
import com.alandevise.tsgate.core.TGTemplate;
import org.springframework.beans.factory.annotation.Autowired;
@Autowired
private TGTemplate tgTemplate;Omitting the database uses the adapter's configured default database:
boolean success = tgTemplate.write(record);Specify a database:
boolean success = tgTemplate.write("tsdb", record);Batch write:
boolean success = tgTemplate.batchWrite("tsdb", records);Use the detailed result when commit boundaries matter. On failure, TSDBBatchWriteException carries the same result object:
BatchWriteResult result = tgTemplate.batchWriteDetailed("tsdb", records);commitState is SUCCESS, NOT_COMMITTED, PARTIALLY_COMMITTED or UNKNOWN. Network errors, HTTP 408 and 5xx responses cannot prove that the current physical batch was not committed. Its state is therefore UNKNOWN, with error code BATCH_COMMIT_UNKNOWN; previously confirmed record and batch counts are retained.
With accept_partial=false, InfluxDB 3 treats HTTP 400/401/403/404/405/413/415/422/429 as a definite rejection of the current batch, reporting zero or partial commitment according to earlier successful requests. InfluxDB 1.x only treats HTTP 401/403/404/405/413/415/429 as definite rejection. HTTP 400 may have committed valid points, so its state is UNKNOWN.
retryable is independent of commit certainty: callers may retry 429, 408 and temporary 5xx responses according to an idempotency strategy; 501/505 do not suggest retry. The adapter does not automatically replay these writes. See the official write documentation for rejection semantics with accept_partial=false.
A single write becomes a one-element collection and is sent immediately as a batch. The starters do not provide asynchronous batch accumulation, unbounded buffering or a backpressure queue.
For the OpenGemini adapter, the complete batch is checked before I/O: measurement names cannot contain comma, semicolon, slash or backslash, equal . or .., or contain non-printable characters. Letters, marks, numbers, punctuation, symbols and ASCII space follow the server's printable-name rule; = is preserved. Invalid names produce ARGUMENT_ERROR with NOT_COMMITTED and zero physical batches; names are never renamed. The inherited line-protocol checks also apply. Once a request is sent, an HTTP 400 partial-write response retains UNKNOWN, as in InfluxDB 1.x.
Adapters consistently throw TSDBException or a subclass. Codes are six-digit 1003xx integers. Use exception.getErrorCode() for the enum or exception.getCode() for its integer value. These classify application errors and are distinct from HTTP status codes.
| Code | Enum | Meaning |
|---|---|---|
| 100300 | CONFIGURATION_ERROR |
Missing required settings, invalid batch limits or pool configuration |
| 100301 | ARGUMENT_ERROR |
Invalid SQL, pagination, predicates, identifiers or write values |
| 100302 | METADATA_ERROR |
Invalid annotation model, physical column, Java type or result mapping |
| 100303 | ADAPTER_STATE_ERROR |
Adapter or underlying client is uninitialized or unavailable |
| 100304 | CONNECTION_ERROR |
Network failure, timeout, unavailable service or rate limit |
| 100305 | PERMISSION_ERROR |
Authentication failure or insufficient permissions |
| 100306 | RESOURCE_NOT_FOUND |
Missing database, table, column or other resource |
| 100307 | WRITE_ERROR |
Definite server rejection with a known commit boundary |
| 100308 | QUERY_ERROR |
Query syntax, execution or response parsing failure |
| 100309 | BATCH_COMMIT_UNKNOWN |
Connection loss after writing or insufficient response evidence to determine the current batch's commit state |
| 100310 | UNSUPPORTED_OPERATION |
Backend capability or call combination unsupported by the shared API |
| 100399 | INTERNAL_ERROR |
Unclassified internal error or compatibility fallback for legacy constructors |
try{
tgTemplate.write(record);
}catch(
TSDBException e){
int code = e.getCode();
String detail = e.getMessage();
Throwable rootCause = e.getCause();
}The application's Web layer maps these codes to its response format and appropriate HTTP statuses. The starters do not register a global exception handler.
-
write,batchWriteandbatchWriteDetailedare synchronous. Successful return means the underlying TSDB acknowledged the write, rather than merely accepting it into an adapter memory queue. - For the OpenGemini adapter, new measurements or tag series become query-visible after asynchronous index merging. When required, the application explicitly polls the expected timestamp, tags and values with a deadline; each adapter query sends one request without a transparent visibility retry.
- Synchronous does not mean globally serialized. Applications may call concurrently; IoTDB SessionPool or InfluxDB HTTP pools reuse connections. Prefer batch APIs for large writes to reduce network round trips.
- Slow databases or exhausted pools propagate latency, timeouts and exceptions to the caller. The adapter does not retain pending data, so there is no unflushed internal buffer to lose on application restart.
- Applications needing asynchronous burst handling, durable retries or reliable delivery should use an application executor, message queue or dedicated data pipeline. These components must choose queue capacity, rejection behavior, persistence, retry and deduplication according to business semantics.
page() and strictCursorPage() only support detail queries. Aggregation requires offset pagination through page(pageNum, pageSize). Aggregate results are stably ordered by window_start + groupByTags, or by groupByTags without a time window. Offset pagination issues an additional total-count query: detail queries count matching source rows, and grouped/aggregate queries count aggregate result rows.
- IoTDB requires the official
ITableSessionPool;tsdb.iotdb.pool.enabled=falsefails application startup. - IoTDB requires a configured default database created in advance. It is set on
TableSessionPoolBuilder; ordinary reads/writes avoid redundantUSEstatements, and the official client restores the default database when a cross-database Session closes. - The previously tested IoTDB SDK 2.0.10 does not reliably replenish a pool slot if restoring the default database fails on Session close. The default database must remain present and the application account must retain access throughout runtime. SDK 2.0.11 still restores the default database when a borrowed Session closes; upgrading the client does not remove the requirement to keep that database available.
- IoTDB waits for a returned Session when the pool is full. Acquisition timeout is returned without replacing the physical pool; other connection exceptions during acquisition also do not trigger replacement. Query execution retains version-aware recovery for the known SDK empty-response defect and connection failures, retrying read-only execution at most once. This does not repair slot leaks during acquisition or add a semaphore across pool generations. When a fault causes pool replacement, draining the old pool and using the new pool can briefly overlap;
max-sizeremains a per-physical-pool limit. - IoTDB assembles batch Tablets by measurement.
tsdb.iotdb.table.tablet-max-row-sizecontrols each Tablet's maximum row count. - IoTDB Tablet RPC compact encoding/compression is enabled by default through
tsdb.iotdb.table.rpc-compression-enabled=true; omission keeps the default. Set it tofalsefor older incompatible servers such as 2.0.2. This is not Thrift transport or disk compression. Verify at least 10 rows in one actual Tablet, rather than only the total application batch, and check the rows after writing. The same setting is used for initial and replacement pools; it does not introduce an automatic write retry or change commit-state reporting. - For null IoTDB field values, types are inferred from non-null values in the same batch. Always-null columns are omitted. A table batch with no inferable field is rejected before I/O.
- IoTDB fields map precisely to
INT32/INT64/FLOAT/DOUBLE/BOOLEAN/STRING/BLOB/DATE. Unsupported Java types are rejected before the first Tablet write. - IoTDB / InfluxDB application batches default to at most
10000records, controlled by each backend'smax-batch-records. - InfluxDB 3 validates and encodes the complete batch before splitting it into HTTP requests of at most
5000lines or1 MiBof UTF-8 payload. Writes useaccept_partial=false. - InfluxDB 1.x also validates the full batch and chunks requests, but HTTP 400 can mean some valid points were written. Such a response yields
UNKNOWN; confirmed counts include only earlier successful requests. Potentially partially committed chunks are not automatically retried. - Both InfluxDB adapters reject measurement names beginning with
#to prevent silent data loss from line-protocol comment interpretation. Measurement=characters and backend-specific backslash rules are encoded appropriately. - InfluxDB integer fields accept Byte/Short/Integer/Long and BigInteger within signed-int64 bounds. BigInteger uses the integer protocol suffix to avoid float64 rounding. Ambiguous Number subclasses are rejected.
- InfluxDB Float/Double values must be finite. InfluxDB 1.x accepts BigDecimal only when exactly representable as float64. InfluxDB 3 permits ordinary double rounding for BigDecimal but rejects overflow and nonzero underflow to zero.
- InfluxDB 1.x additionally rejects
_field,_measurementandtimeas tag or field keys, avoiding data loss or rejection caused by reserved protocol names. - A batch is not a database transaction across multiple Tablets or HTTP requests. Conversion or validation failure before I/O confirms zero writes for the whole batch. After I/O starts, inspect
BatchWriteResult.commitStatefor successful, uncommitted, partially committed or unknown outcomes. - Query/pagination
limit/pageSizemust be in1–10000. Offset arithmetic overflow fails explicitly. - Adapters write synchronously and maintain no asynchronous buffer. If incoming application traffic can exceed database or network write capacity, implement rate limiting, burst handling, retry and backpressure in the application or a dedicated data pipeline.
← Configuration and database selection · Fluent queries and aggregation →
The tested 1.4.1/1.5.2 Influx-compatible HTTP write path converts integer fields through float64 before storing them. An integer protocol suffix does not prevent this conversion: 9007199254740993i reads back as 9007199254740992. The OpenGemini adapter therefore checks the complete batch before I/O and accepts integer-typed fields only within signed-int64 bounds and when their exact value is representable by IEEE 754 float64. All integers from -2^53 to 2^53 are exact; some larger values, including 2^53+2 and Long.MIN_VALUE, are also exact. 2^53+1, Long.MAX_VALUE and Long.MIN_VALUE+1 are rejected with ARGUMENT_ERROR, NOT_COMMITTED and zero physical requests, without coercion or string encoding. Structured query/count also preflight exact integer filter literals, including every IN/BETWEEN value, because backend numeric comparisons can round them. Extreme integer-valued BigDecimal predicates are compared with signed-int64 bounds before integer expansion, so very large exponents cannot bypass validation or force unbounded allocation. Float/Double and fractional query literals retain ordinary floating-point semantics; existing BigDecimal field checks still apply. Epoch-millisecond timestamps use their separate time path. Native SQL and borrowed native writes bypass these checks and retain backend precision limitations; aggregate overflow and floating-point accumulation are not made exact by this validation. This restriction is specific to the HTTP adapter, not a claim about every OpenGemini engine or alternate ingestion protocol.
TsGate 2.1.0 includes the independent OpenGemini adapter and starter. See OpenGemini integration for configuration, default-engine limits and exact-version testing, and 2.1.0 release notes for migration requirements.
TsGate · Wiki home · 文档首页 · Apache-2.0 · NOTICE
Compatibility claims apply only to documented capabilities and verified versions. 兼容性承诺仅适用于已列明的能力和已验证的版本。