or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cursor-navigation.mddatabase-operations.mdenhanced-database.mdindex-operations.mdindex.mdobject-store-operations.mdpromise-wrapping.mdtransaction-management.md
tile.json

transaction-management.mddocs/

0

# Transaction Management

1

2

Enhanced transaction interface with automatic completion handling and convenient store access.

3

4

## Capabilities

5

6

### Transaction Properties

7

8

Access transaction metadata and associated objects.

9

10

```typescript { .api }

11

/**

12

* The transaction's mode

13

*/

14

readonly mode: Mode;

15

16

/**

17

* The names of stores in scope for this transaction

18

*/

19

readonly objectStoreNames: TypedDOMStringList<TxStores[number]>;

20

21

/**

22

* The transaction's connection

23

*/

24

readonly db: IDBPDatabase<DBTypes>;

25

26

/**

27

* Promise for the completion of this transaction

28

* Resolves when transaction completes successfully

29

* Rejects if transaction is aborted or encounters an error

30

*/

31

readonly done: Promise<void>;

32

33

/**

34

* The associated object store, if the transaction covers a single store

35

* Undefined if transaction covers multiple stores

36

*/

37

readonly store: TxStores[1] extends undefined

38

? IDBPObjectStore<DBTypes, TxStores, TxStores[0], Mode>

39

: undefined;

40

```

41

42

**Usage Examples:**

43

44

```typescript

45

import { openDB } from "idb";

46

47

const db = await openDB("my-database");

48

49

// Single store transaction

50

const tx = db.transaction("users", "readwrite");

51

console.log("Transaction mode:", tx.mode); // "readwrite"

52

console.log("Store names:", [...tx.objectStoreNames]); // ["users"]

53

54

// Access single store directly

55

const userStore = tx.store; // Available because only one store

56

await userStore.add({ name: "Alice" });

57

await tx.done; // Wait for transaction completion

58

59

// Multiple store transaction

60

const tx2 = db.transaction(["users", "posts"], "readwrite");

61

console.log("Store names:", [...tx2.objectStoreNames]); // ["users", "posts"]

62

console.log("Direct store access:", tx2.store); // undefined (multiple stores)

63

64

// Must access stores explicitly

65

const userStore2 = tx2.objectStore("users");

66

const postStore = tx2.objectStore("posts");

67

```

68

69

### Object Store Access

70

71

Get object stores within the transaction scope.

72

73

```typescript { .api }

74

/**

75

* Returns an IDBObjectStore in the transaction's scope

76

* @param name - Name of the object store

77

* @returns Enhanced object store interface

78

*/

79

objectStore<StoreName extends TxStores[number]>(

80

name: StoreName

81

): IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;

82

```

83

84

**Usage Examples:**

85

86

```typescript

87

// Single store transaction with explicit access

88

const tx = db.transaction("users", "readwrite");

89

const userStore = tx.objectStore("users");

90

await userStore.add({ name: "Bob" });

91

92

// Multiple store transaction

93

const tx2 = db.transaction(["users", "posts"], "readwrite");

94

const userStore2 = tx2.objectStore("users");

95

const postStore = tx2.objectStore("posts");

96

97

// Add user and their first post in same transaction

98

const userId = await userStore2.add({ name: "Charlie", email: "charlie@example.com" });

99

await postStore.add({ title: "My First Post", authorId: userId });

100

101

await tx2.done; // Both operations complete together

102

```

103

104

### Transaction Completion

105

106

Handle transaction completion and error scenarios.

107

108

```typescript { .api }

109

/**

110

* Promise that resolves when the transaction completes successfully

111

* Rejects if the transaction is aborted or encounters an error

112

*/

113

readonly done: Promise<void>;

114

```

115

116

**Transaction Completion Examples:**

117

118

```typescript

119

// Basic transaction completion

120

const tx = db.transaction("users", "readwrite");

121

try {

122

await tx.store.add({ name: "Alice" });

123

await tx.store.add({ name: "Bob" });

124

await tx.done; // Wait for both operations to complete

125

console.log("Transaction completed successfully");

126

} catch (error) {

127

console.log("Transaction failed:", error);

128

}

129

130

// Multiple operations with error handling

131

const tx2 = db.transaction(["users", "posts"], "readwrite");

132

const userStore = tx2.objectStore("users");

133

const postStore = tx2.objectStore("posts");

134

135

try {

136

// These operations are atomic - all succeed or all fail

137

const userId = await userStore.add({ name: "Dave" });

138

await postStore.add({ title: "Post 1", authorId: userId });

139

await postStore.add({ title: "Post 2", authorId: userId });

140

141

await tx2.done; // Ensure everything is committed

142

console.log("User and posts created successfully");

143

} catch (error) {

144

console.log("Failed to create user and posts:", error);

145

// All operations are rolled back automatically

146

}

147

148

// Transaction with conditional operations

149

const tx3 = db.transaction(["users", "settings"], "readwrite");

150

try {

151

const existingUser = await tx3.objectStore("users").get("user123");

152

153

if (!existingUser) {

154

await tx3.objectStore("users").add({ id: "user123", name: "New User" });

155

await tx3.objectStore("settings").add({ userId: "user123", theme: "dark" });

156

} else {

157

await tx3.objectStore("users").put({ ...existingUser, lastLogin: new Date() });

158

}

159

160

await tx3.done;

161

} catch (error) {

162

console.log("Transaction failed:", error);

163

}

164

```

165

166

### Transaction Options

167

168

Configure transaction behavior with durability and other options.

169

170

```typescript { .api }

171

interface IDBTransactionOptions {

172

/**

173

* The durability of the transaction

174

* - "default": Browser's default durability behavior

175

* - "strict": Ensures data is written to disk before completion

176

* - "relaxed": Better performance with fewer guarantees

177

*/

178

durability?: 'default' | 'strict' | 'relaxed';

179

}

180

```

181

182

**Transaction Options Examples:**

183

184

```typescript

185

// High durability for critical data

186

const criticalTx = db.transaction("financial_records", "readwrite", {

187

durability: "strict"

188

});

189

await criticalTx.store.add({ amount: 1000, type: "deposit" });

190

await criticalTx.done; // Guaranteed to be written to disk

191

192

// Better performance for temporary data

193

const cacheTx = db.transaction("cache", "readwrite", {

194

durability: "relaxed"

195

});

196

await cacheTx.store.put({ key: "temp_data", value: someData });

197

await cacheTx.done; // May complete before writing to disk

198

199

// Default durability (most common)

200

const normalTx = db.transaction("users", "readwrite", {

201

durability: "default"

202

});

203

await normalTx.store.add({ name: "User" });

204

await normalTx.done;

205

```

206

207

### Advanced Transaction Patterns

208

209

Complex transaction workflows and patterns.

210

211

**Batch Operations:**

212

213

```typescript

214

async function batchInsertUsers(users: User[]) {

215

const tx = db.transaction("users", "readwrite");

216

const userStore = tx.store;

217

218

// Start all operations without awaiting

219

const promises = users.map(user => userStore.add(user));

220

221

// Wait for all operations to complete

222

await Promise.all([...promises, tx.done]);

223

224

console.log(`Successfully added ${users.length} users`);

225

}

226

```

227

228

**Transaction Rollback on Custom Conditions:**

229

230

```typescript

231

async function transferBetweenAccounts(fromId: string, toId: string, amount: number) {

232

const tx = db.transaction("accounts", "readwrite");

233

const accountStore = tx.store;

234

235

try {

236

const fromAccount = await accountStore.get(fromId);

237

const toAccount = await accountStore.get(toId);

238

239

if (!fromAccount || !toAccount) {

240

throw new Error("Account not found");

241

}

242

243

if (fromAccount.balance < amount) {

244

throw new Error("Insufficient funds");

245

}

246

247

// Update balances

248

await accountStore.put({

249

...fromAccount,

250

balance: fromAccount.balance - amount

251

});

252

253

await accountStore.put({

254

...toAccount,

255

balance: toAccount.balance + amount

256

});

257

258

await tx.done; // Commit the transaction

259

console.log("Transfer completed successfully");

260

261

} catch (error) {

262

// Transaction automatically rolls back on error

263

console.log("Transfer failed:", error.message);

264

throw error;

265

}

266

}

267

```

268

269

**Long-running Transactions with Progress Tracking:**

270

271

```typescript

272

async function processLargeDataset(data: any[]) {

273

const batchSize = 100;

274

const totalBatches = Math.ceil(data.length / batchSize);

275

276

for (let i = 0; i < totalBatches; i++) {

277

const batch = data.slice(i * batchSize, (i + 1) * batchSize);

278

const tx = db.transaction("processed_data", "readwrite");

279

280

try {

281

for (const item of batch) {

282

await tx.store.add(processItem(item));

283

}

284

285

await tx.done;

286

console.log(`Processed batch ${i + 1}/${totalBatches}`);

287

288

} catch (error) {

289

console.log(`Failed to process batch ${i + 1}:`, error);

290

throw error;

291

}

292

}

293

}

294

```

295

296

### Transaction Lifecycle

297

298

Understanding transaction states and lifecycle management.

299

300

```typescript

301

// Transaction begins when created

302

const tx = db.transaction("users", "readwrite");

303

304

// Transaction is active during operations

305

const userStore = tx.store;

306

await userStore.add({ name: "Alice" });

307

308

// Transaction can be explicitly aborted

309

// tx.abort(); // Would cause tx.done to reject

310

311

// Transaction completes when all operations finish

312

// and no more operations are queued

313

await tx.done; // Transaction is now complete

314

315

// Attempting operations after completion throws error

316

// await userStore.add({ name: "Bob" }); // Would throw TransactionInactiveError

317

```