Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

SQLite バックエンドの Durable Object Storage

最終更新 Markdown で表示Agent セットアップ

Durable Object Storage API を使うと、Durable Objects はトランザクション対応で強い一貫性を持つストレージにアクセスできます。Durable Object に付属するストレージは、その一意なインスタンス専用であり、ほかのオブジェクトからはアクセスできません。

Durable Object Storage API には、SQL、ポイントインタイムリカバリ(PITR)、キーバリュー(KV)、アラーム API など、いくつかのメソッドがあります。利用できる API メソッドは、Durable Objects クラスのストレージバックエンドが SQLiteKV かによって異なります。

メソッド 1 SQLite バックエンドの Durable Object クラス KV バックエンドの Durable Object クラス
SQL API
PITR API
Synchronous KV API 2, 3
Asynchronous KV API 3
Alarms API

脚注

1 各メソッドは暗黙的にトランザクションでラップされます。複数のキーバリューペアにアクセスする場合でも、結果はアトミックであり、ほかのストレージ操作から分離されます。

2 get()put()delete()list() などの KV API メソッドは、隠し SQLite テーブル __cf_kv にデータを保存します。テーブル一覧ではこのテーブルを確認できますが、SQL API から中身へアクセスすることはできません。

3 SQLite バックエンドの Durable Objects は ctx.storage.kv を使う 同期 KV API メソッド も利用します。一方、KV バックエンドの Durable Objects が提供するのは 非同期 KV API メソッド だけです。

ストレージへのアクセス

Durable Objects は DurableObjectStorage インターフェイス経由で Storage API にアクセスし、DurableObjectState::storage プロパティで使います。Durable Object のコンストラクターに渡される ctx パラメーターを使い、this.ctx.storage で参照することが多いです。

次のコードスニペットは、Durable Object Storage API でデータを保存・取得する方法を示します。

export class Counter extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);
	}

	async increment() {
		let value = (await this.ctx.storage.get("value")) || 0;
		value += 1;
		await this.ctx.storage.put("value", value);
		return value;
	}
}
export class Counter extends DurableObject {
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
  }

    async increment(): Promise<number> {
      let value: number = (await this.ctx.storage.get('value')) || 0;
      value += 1;
      await this.ctx.storage.put('value', value);
      return value;
    }

}
from workers import DurableObject

class Counter(DurableObject):
  def __init__(self, ctx, env):
    super().__init__(ctx, env)

  async def increment(self):
    value = (await self.ctx.storage.get('value')) or 0
    value += 1
    await self.ctx.storage.put('value', value)
    return value

JavaScript はシングルスレッドのイベント駆動言語です。そのため JavaScript ランタイムは、デフォルトではリクエスト同士の実行が入り交じることがあり、並行性の不具合につながることがあります。Durable Objects ランタイムは、input gatesoutput gates を組み合わせて、ストレージ操作時にこの種の並行性の不具合を防ぎます。詳細は ブログ記事 を参照してください。

SQL API

SqlStorage インターフェイスは、Durable Object に埋め込まれた SQLite データベースを変更するメソッドをまとめたものです。SqlStorage インターフェイスは、DurableObjectStorage クラスの sql プロパティ から使えます。

たとえば、sql.exec() でテーブルを作成し、行を挿入できます。

import { DurableObject } from "cloudflare:workers";

export class MyDurableObject extends DurableObject {
  sql: SqlStorage;
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sql = ctx.storage.sql;

    this.sql.exec(`
      CREATE TABLE IF NOT EXISTS artist(
        artistid    INTEGER PRIMARY KEY,
        artistname  TEXT
      );
      INSERT INTO artist (artistid, artistname) VALUES
        (123, 'Alice'),
        (456, 'Bob'),
        (789, 'Charlie');
    `);
  }
}
from workers import DurableObject

class MyDurableObject(DurableObject):
  def __init__(self, ctx, env):
    super().__init__(ctx, env)
    self.sql = ctx.storage.sql

    self.sql.exec("""
      CREATE TABLE IF NOT EXISTS artist(
        artistid    INTEGER PRIMARY KEY,
        artistname  TEXT
      );
      INSERT INTO artist (artistid, artistname) VALUES
        (123, 'Alice'),
        (456, 'Bob'),
        (789, 'Charlie');
    """)

Durable Objects support 追加機能として、次を含む SQLite 拡張の一部を利用できます。

対応している関数の一覧は、ソースコード を参照してください。

exec

exec(query: string, ...bindings: any[]): SqlStorageCursor

パラメーター

  • query: string
    • 実行する SQL クエリ文字列です。query にはパラメーターバインディング用の ? プレースホルダーを含められます。セミコロンで区切った複数の SQL 文を query で実行できます。複数の SQL 文がある場合、パラメーターバインディングは query 内の最後の SQL 文に適用され、返されるカーソルも最後の SQL 文だけが対象です。
  • ...bindings: any[] Optional
    • query 内の ? プレースホルダーに対応する、任意個の引数です。

戻り値

クエリ結果の行をオブジェクトとして反復するためのカーソル(SqlStorageCursor)です。SqlStorageCursor は JavaScript の Iterable であり、for (let row of cursor) で反復できます。SqlStorageCursor は JavaScript の Iterator でもあり、cursor.next() でも反復できます。

SqlStorageCursor は次のメソッドをサポートします。

  • next()
    • カーソルの次の値を表すオブジェクトを返します。返されるオブジェクトには、JavaScript の Iterator に従う donevalue プロパティがあります。次の値があるときは donefalse で、value はクエリ結果の次の行オブジェクトです。カーソルをすべて使い切ると donetrue になり、value は設定されません。
  • toArray()
    • 残りのカーソル値を反復し、返された行オブジェクトの配列を返します。
  • one()
    • クエリ結果がちょうど 1 行のとき、その行オブジェクトを返します。0 行または 2 行以上の場合、one() は例外を投げます。
  • raw(): Iterator
    • 同じクエリ結果に対する Iterator を返します。各行はオブジェクトではなく、列名なしの列値の配列です。
    • 返される Iterator は、上記の next()toArray() メソッドをサポートします。
    • 返されるカーソルと raw() イテレーターは同じクエリ結果を反復し、組み合わせて使えます。例:
let cursor = this.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;");
let rawResult = cursor.raw().next();

if (!rawResult.done) {
  console.log(rawResult.value); // prints [ 123, 'Alice' ]
} else {
  // query returned zero results
}

console.log(cursor.toArray()); // prints [{ artistid: 456, artistname: 'Bob' },{ artistid: 789, artistname: 'Charlie' }]
cursor = self.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;")
raw_result = cursor.raw().next()

if not raw_result.done:
  print(raw_result.value)  # prints [ 123, 'Alice' ]
else:
  # query returned zero results
  pass

print(cursor.toArray())  # prints [{ artistid: 456, artistname: 'Bob' },{ artistid: 789, artistname: 'Charlie' }]

SqlStorageCursor には次のプロパティがあります。

  • columnNames: string[]
    • raw イテレーターが返す各行配列に現れる順の、クエリの列名です。
  • rowsRead: number
    • この SQL query でこれまでに読み取った行数です。カーソルを反復すると増えることがあります。最終値は SQL 課金 に使われます。
  • rowsWritten: number
    • この SQL query でこれまでに書き込んだ行数です。カーソルを反復すると増えることがあります。最終値は SQL 課金 に使われます。
  • 列の数値は、JavaScript の数値の 52 ビット精度の影響を受けます。非常に大きな数(int64)を保存して同じ値を取り出すと、元の数より精度が落ちることがあります。

以降の SQL API の例では、次の SQL スキーマを使います。

import { DurableObject } from "cloudflare:workers";

export class MyDurableObject extends DurableObject {
  sql: SqlStorage
  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    this.sql = ctx.storage.sql;

    this.sql.exec(`CREATE TABLE IF NOT EXISTS artist(
      artistid    INTEGER PRIMARY KEY,
      artistname  TEXT
    );INSERT INTO artist (artistid, artistname) VALUES
      (123, 'Alice'),
      (456, 'Bob'),
      (789, 'Charlie');`
    );
  }
}

クエリ結果を行オブジェクトとして反復します。

  let cursor = this.sql.exec("SELECT * FROM artist;");

  for (let row of cursor) {
    // Iterate over row object and do something
  }

クエリ結果を行オブジェクトの配列に変換します。

  // Return array of row objects: [{"artistid":123,"artistname":"Alice"},{"artistid":456,"artistname":"Bob"},{"artistid":789,"artistname":"Charlie"}]
  let resultsArray1 = this.sql.exec("SELECT * FROM artist;").toArray();
  // OR
  let resultsArray2 = Array.from(this.sql.exec("SELECT * FROM artist;"));
  // OR
  let resultsArray3 = [...this.sql.exec("SELECT * FROM artist;")]; // JavaScript spread syntax

クエリ結果を、行の値配列の配列に変換します。

  // Returns [[123,"Alice"],[456,"Bob"],[789,"Charlie"]]
  let cursor = this.sql.exec("SELECT * FROM artist;");
  let resultsArray = cursor.raw().toArray();

  // Returns ["artistid","artistname"]
  let columnNameArray = this.sql.exec("SELECT * FROM artist;").columnNames.toArray();

クエリ結果の最初の行オブジェクトを取得します。

  // Returns {"artistid":123,"artistname":"Alice"}
  let firstRow = this.sql.exec("SELECT * FROM artist ORDER BY artistname DESC;").toArray()[0];

クエリ結果がちょうど 1 行かどうかを確認します。

  // returns error
  this.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;").one();

  // returns { artistid: 123, artistname: 'Alice' }
  let oneRow = this.sql.exec("SELECT * FROM artist WHERE artistname = ?;", "Alice").one()

返されるカーソルの動作:

  let cursor = this.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;");
  let result = cursor.next();
  if (!result.done) {
    console.log(result.value); // prints { artistid: 123, artistname: 'Alice' }
  } else {
    // query returned zero results
  }

  let remainingRows = cursor.toArray();
  console.log(remainingRows); // prints [{ artistid: 456, artistname: 'Bob' },{ artistid: 789, artistname: 'Charlie' }]

返されるカーソルと raw() イテレーターは、同じクエリ結果を反復します。

  let cursor = this.sql.exec("SELECT * FROM artist ORDER BY artistname ASC;");
  let result = cursor.raw().next();

  if (!result.done) {
    console.log(result.value); // prints [ 123, 'Alice' ]
  } else {
    // query returned zero results
  }

  console.log(cursor.toArray()); // prints [{ artistid: 456, artistname: 'Bob' },{ artistid: 789, artistname: 'Charlie' }]

sql.exec().rowsRead():

  let cursor = this.sql.exec("SELECT * FROM artist;");
  cursor.next()
  console.log(cursor.rowsRead); // prints 1

  cursor.toArray(); // consumes remaining cursor
  console.log(cursor.rowsRead); // prints 3

databaseSize

databaseSize: number

戻り値

現在の SQLite データベースサイズ(バイト)です。

let size = ctx.storage.sql.databaseSize;
size = ctx.storage.sql.databaseSize

PITR(Point In Time Recovery)API

SQLite バックエンドの Durable Objects では、埋め込み SQLite データベースを過去 30 日以内の任意の時点に復元する、ポイントインタイムリカバリー(PITR)API メソッドが使えます。これらのメソッドは SQLite データベース全体に適用され、オブジェクトの保存済み SQL データと、キーバリュー put() API で保存したキーバリューデータの両方を含みます。PITR API はローカル開発では使えません。データの変更の永続ログがローカルに保存されないためです。

PITR API は時点を「ブックマーク」で表します。ブックマークは、ほぼ英数字の文字列です。例は 0000007b-0000b26e-00001538-0c3e87bb37b3db5cc52eedb93cd3b96b です。ブックマークは辞書順で比較できるように設計されています。より早い時点のブックマークは、通常の文字列比較で、より遅い時点のブックマークより小さくなります。

getCurrentBookmark

ctx.storage.getCurrentBookmark(): Promise<string>

  • オブジェクトの履歴における現在の時点を表すブックマークを返します。

getBookmarkForTime

ctx.storage.getBookmarkForTime(timestamp: number | Date): Promise<string>

  • 指定した時点におおよそ対応するブックマークを返します。時点は過去 30 日以内である必要があります。タイムスタンプが数値の場合、new Date(timestamp) を使ったときと同じ方法で日付に変換されます。

onNextSessionRestoreBookmark

ctx.storage.onNextSessionRestoreBookmark(bookmark: string): Promise<string>

  • 次に再起動したとき、ストレージが指定したブックマーク時点の内容と完全に一致するよう Durable Object を設定します。このあと、アプリケーションは通常 ctx.abort() を呼んで Durable Object を再起動し、ポイントインタイムリカバリーを完了します。

このメソッドは、リカバリーが行われる直前の時点を表す特別なブックマークを返します(その時点はまだ技術的には未来です)。そのため、リカバリー完了後に、このブックマークへ再度リカバリーすれば元に戻せます。

const DAY_MS = 24*60*60*1000;
// restore to 2 days ago
let bookmark = ctx.storage.getBookmarkForTime(Date.now() - 2 * DAYS_MS);
ctx.storage.onNextSessionRestoreBookmark(bookmark);
from datetime import datetime, timedelta

now = datetime.now()
# restore to 2 days ago
bookmark = ctx.storage.getBookmarkForTime(now - timedelta(days=2))
ctx.storage.onNextSessionRestoreBookmark(bookmark)

同期 KV API

get

  • ctx.storage.kv.get(key string): Any, undefined
    • 指定したキーに対応する値を取得します。戻り値の型は、そのキーに以前書き込まれた値と同じです。キーが存在しない場合は undefined です。

put

delete

  • ctx.storage.kv.delete(key string): boolean
    • キーと対応する値を削除します。キーが存在した場合は true、存在しなかった場合は false を返します。

list

  • ctx.storage.kv.list(options Object 任意): Iterable<string, any>
    • 現在の Durable Object に関連付けられたすべてのキーと値を、キーの UTF-8 エンコーディングに基づく昇順で返します。

    • Iterable 内の各戻り値の型は、対応するキーに以前書き込まれた値と同じです。

    • オプションなしでこの list を呼ぶ前に、Durable Object にどれだけデータが保存されているかに注意してください。すべてのデータが Durable Object のメモリに読み込まれ、上限 に達する可能性があります。それが心配な場合は、以下で説明するオプションを list に渡してください。

利用できるオプション

  • start string

    • リスト結果の開始キーです。このキーを含みます。
  • startAfter string

    • リスト結果の開始位置となるキーの直後です。このキーは含みません。start と同時には使えません。
  • end string

    • リスト結果の終了キーです。このキーは含みません。
  • prefix string

    • キーがこのプレフィックスで始まるキーと値のペアだけに結果を限定します。
  • reverse boolean

    • true の場合、デフォルトの昇順ではなく降順で結果を返します。
    • reverse を有効にしても、startstartKeyendKey の意味は変わりません。start は辞書順で返せる最小のキー(含む)を定義し、降順リストでは実質的な終点になります。end は辞書順でリストが対象とする最大のキー(含まない)を定義し、降順リストでは実質的な始点になります。
  • limit number

    • 返すキーと値のペアの最大数です。

非同期 KV API

get

  • ctx.storage.get(key string, options Object 任意): Promise<any>

    • 指定したキーに対応する値を取得します。戻り値の型は、そのキーに以前書き込まれた値と同じです。キーが存在しない場合は undefined です。
  • ctx.storage.get(keys Array<string>, options Object 任意): Promise<Map<string, any>>

    • 指定した各キーに対応する値を取得します。Map 内の各戻り値の型は、対応するキーに以前書き込まれた値と同じです。Map の結果は UTF-8 エンコーディングの昇順で並び、存在しないキーは省略されます。一度に最大 128 個のキーを指定できます。

利用できるオプション

  • allowConcurrency: boolean

    • デフォルトでは、予期しない競合状態を避けるため、ストレージ操作の実行中は Object への I/O イベントの配信を一時停止します。この動作を無効にして同時イベントの配信を許可するには、allowConcurrency: true を渡します。
  • noCache: boolean

    • true の場合、キーと値はメモリ内キャッシュに挿入されません。キーがすでにキャッシュにある場合はキャッシュされた値を返しますが、最終使用時刻は更新しません。近い将来このキーを使わない見込みのときに使います。このフラグはヒントです。コードの意味は変わりませんが、パフォーマンスに影響する場合があります。

put

  • put(key string, value any, options Object 任意): Promise

    • 値を保存し、指定したキーに関連付けます。値は structured clone algorithm がサポートする任意の型を使えます。ほとんどの型が対象です。

      キーと値のサイズ上限は、利用している Durable Object のストレージバックエンドによって異なります。次のいずれかを参照してください。

      KV バックエンドの Durable Object では、シリアライズ後の値が 128 KiB(131072 バイト)の値サイズ上限を超えると、書き込みが適用される前に put()RangeError を投げます(例: Values cannot be larger than 131072 bytes.)。

  • put(entries Object, options Object 任意): Promise

delete

  • delete(key string, options Object 任意): Promise<boolean>

    • キーと対応する値を削除します。キーが存在した場合は true、存在しなかった場合は false を返します。
  • delete(keys Array<string>, options Object 任意): Promise<number>

    • 指定したキーと対応する値を削除します。一度に最大 128 個のキーを指定できます。削除したキーと値のペアの数を返します。

利用できるオプション

  • put()delete()deleteAll() は次のオプションをサポートします。

  • allowUnconfirmed boolean

    • デフォルトでは、以前の書き込みがディスクへフラッシュされたことを確認するまで、Durable Object からの送信ネットワークメッセージを一時停止します。書き込みが失敗した場合、システムは Object をリセットし、送信中のメッセージをすべて破棄して、クライアントにはエラーを返します。

    • こうすることで、書き込みが実際に成功しない限り外部から Object の動作は観測できないため、Durable Objects は書き込みが完了する前に確定してしまう心配なく、書き込みと並行して実行を続けられます。

    • 書き込みのあと、後続のネットワークメッセージがわずかに遅れることがあります。未確認の書き込みを前提に通信しても問題ないアプリケーションもあります。ネットワークトラフィックをすぐに許可したいプログラムもあります。その場合は allowUnconfirmedtrue に設定し、デフォルトの動作を無効にします。

    • 一部の送信ネットワークメッセージだけをすぐに進めたい場合は、allowUnconfirmed オプションで進めたいメッセージのブロックを避け、別途 sync() を呼びます。sync() は、以前の書き込みがすべてディスクへ正常に永続化されたときにだけ解決する Promise を返します。

  • noCache boolean

    • true の場合、ディスクへの書き込みが完了した時点で、キーと値はメモリから破棄されます。

    • 近い将来キーを使わない場合は noCache を使います。noCache はコードの意味を変えませんが、パフォーマンスに影響する場合があります。

    • 書き込み完了前に get() でキーを取得した場合は、書き込みバッファーのコピーが返されます。これにより、最新の put() 呼び出しとの一貫性が保たれます。

list

  • list(options Object 任意): Promise<Map<string, any>>
    • 現在の Durable Object に関連付けられたすべてのキーと値を、キーの UTF-8 エンコーディングに基づく昇順で返します。

    • Map 内の各戻り値の型は、対応するキーに以前書き込まれた値と同じです。

    • オプションなしでこの list を呼ぶ前に、Durable Object にどれだけデータが保存されているかに注意してください。すべてのデータが Durable Object のメモリに読み込まれ、上限 に達する可能性があります。それが心配な場合は、以下で説明するオプションを list に渡してください。

利用できるオプション

  • start string

    • リスト結果の開始キーです。このキーを含みます。
  • startAfter string

    • リスト結果の開始位置となるキーの直後です。このキーは含みません。start と同時には使えません。
  • end string

    • リスト結果の終了キーです。このキーは含みません。
  • prefix string

    • キーがこのプレフィックスで始まるキーと値のペアだけに結果を限定します。
  • reverse boolean

    • true の場合、デフォルトの昇順ではなく降順で結果を返します。
    • reverse を有効にしても、startstartKeyendKey の意味は変わりません。start は辞書順で返せる最小のキー(含む)を定義し、降順リストでは実質的な終点になります。end は辞書順でリストが対象とする最大のキー(含まない)を定義し、降順リストでは実質的な始点になります。
  • limit number

    • 返すキーと値のペアの最大数です。
  • allowConcurrency boolean

    • 上記の get() のオプションと同じです。
  • noCache boolean

    • 上記の get() のオプションと同じです。

Alarms

getAlarm

  • getAlarm(options Object 任意): Promise<Number | null>
    • 現在のアラーム時刻(設定されている場合)を、エポックからの整数ミリ秒として取得します。アラームは、まだ開始していない場合、または失敗して再試行が始まっていない場合に、設定済みとみなされます。アラームが設定されていない場合、getAlarm()null を返します。

利用できるオプション

  • get() と同じオプションです。ただし noCache はありません。

setAlarm

  • setAlarm(scheduledTime Date | number, options Object 任意): Promise

    • 現在のアラーム時刻を設定します。JavaScript の Date、またはエポックからの整数ミリ秒を受け付けます。

    setAlarm()Date.now() 以前の時刻を渡した場合、アラームはすぐあとで非同期実行されるようスケジュールされます。このときアラームハンドラーが実行中でも、キャンセルはされません。アラームはミリ秒単位で設定でき、通常は設定時刻の数ミリ秒後に実行されます。ただしメンテナンスやフェイルオーバー中の障害により、最大 1 分遅れることがあります。

deleteAlarm

  • deleteAlarm(options Object 任意): Promise
    • アラームが存在する場合は削除します。アラームハンドラーが実行中の場合はキャンセルしません。

利用できるオプション

  • setAlarm()deleteAlarm()put() と同じオプションをサポートします。ただし noCache はありません。

その他

deleteAll

  • deleteAll(options Object 任意): Promise
    • 保存されているデータをすべて削除し、Durable Object が使っているストレージを実質的に解放します。キーバリューストレージバックエンドの Durable Object では、deleteAll() はその Durable Object のすべてのキーと対応する値を削除します。SQLite ストレージバックエンド の Durable Object では、deleteAll() はその Durable Object のプライベート SQLite データベースの内容をすべて削除します。SQL データとキーバリューデータの両方が対象です。
    • キーバリューストレージバックエンドの Durable Object では、進行中の deleteAll() が失敗し、一部のデータだけが残ることがあります。SQLite ストレージバックエンドの Durable Object では、deleteAll() はアトミック(すべて成功するか、まったく実行されないか)なので、部分削除の問題はありません。
    • 互換日付が 2026-02-24 以降の Workers では、deleteAll() は有効な アラーム も削除します。それより前の互換日付では、deleteAll() はアラームを削除しません。別途 deleteAlarm() を使うか、delete_all_deletes_alarm 互換フラグ を有効にしてください。

transactionSync

  • transactionSync(callback): any
    • SQLite バックエンドの Durable Object でのみ利用できます。

    • callback() をトランザクションで包んで実行し、その結果を返します。

    • callback() が例外を投げた場合、トランザクションはロールバックされます。

    • コールバックは同期的に完了する必要があります。つまり、async として宣言したり、Promise を返したりしてはいけません。トランザクションに含められるのは同期的なストレージ操作だけです。これは、同期的に完了する ctx.storage.sql.exec() を使った SQL クエリ向けです。

transaction

  • transaction(closureFunction(txn)): Promise

    • txn に対して呼ばれた一連のストレージ操作を、1 つのトランザクションとして実行します。コミットに成功するか、中止されます。

    • 明示的なトランザクションは、もはや必要ありません。間に await を挟まない一連の書き込み操作は、自動的にアトミックに送信されます。また、読み取り操作を await している間は、システムが同時イベントの実行を防ぎます(allowConcurrency: true を使っている場合を除く)。そのため、一連の読み取りのあとに一連の書き込み(間にほかの I/O がない場合)は自動的にアトミックになり、トランザクションのように振る舞います。

  • txn

    • 上記で説明した put()get()delete()list() メソッドに、現在のトランザクションコンテキストでアクセスできます。トランザクションクロージャ内でトランザクションの振る舞いを得るには、トップレベルの ctx.storage オブジェクトではなく、txn オブジェクトのメソッドを呼ぶ必要があります。

      また、トランザクション中の変更をコミットせずにロールバックする rollback() 関数も使えます。rollback() を呼んだあと、txn オブジェクトへの以降の操作は例外で失敗します。rollback() はパラメーターを取らず、呼び出し元に何も返しません。

    • SQLite バックエンドのストレージエンジン を使う場合、txn オブジェクトは不要です。ctx.storage オブジェクトに対して直接行うストレージ操作(ctx.storage.sql.exec() を使った SQL クエリを含む)は、トランザクションの一部と見なされます。

sync

  • sync(): Promise
    • 保留中の書き込みをディスクへ同期します。

    • 自動的な書き込み合体(write coalescing)の通常の振る舞いと似ています。書き込みバッファーに保留中の書き込みがある場合(allowUnconfirmed オプション で送信したものも含む)、返される Promise はそれらが完了したときに解決します。保留中の書き込みがない場合、返される Promise はすでに解決済みです。

ストレージのプロパティ

sql

sqlDurableObjectStorage 型の読み取り専用プロパティで、SQL API をまとめたものです。

関連リソース

役に立ちましたか?