or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-queuing.mdconfiguration-settings.mdconnection-management.mdconnection-pools.mddata-types-lobs.mdindex.mdsoda-operations.mdsql-execution.mdtransaction-management.md

transaction-management.mddocs/

0

# Transaction Management

1

2

Comprehensive transaction control including commit, rollback, and distributed transaction support.

3

4

## Capabilities

5

6

### Basic Transaction Control

7

8

Standard transaction operations for database consistency.

9

10

```javascript { .api }

11

/**

12

* Commits the current transaction

13

* @returns Promise that resolves when transaction is committed

14

*/

15

commit(): Promise<void>;

16

17

/**

18

* Rolls back the current transaction

19

* @returns Promise that resolves when transaction is rolled back

20

*/

21

rollback(): Promise<void>;

22

```

23

24

**Usage Examples:**

25

26

```javascript

27

const oracledb = require('oracledb');

28

29

// Manual transaction control

30

oracledb.autoCommit = false; // Disable auto-commit

31

32

const connection = await oracledb.getConnection(config);

33

34

try {

35

// Execute multiple related operations

36

await connection.execute(

37

'INSERT INTO orders (order_id, customer_id, total) VALUES (:1, :2, :3)',

38

[1001, 'CUST001', 199.99]

39

);

40

41

await connection.execute(

42

'INSERT INTO order_items (order_id, product_id, quantity) VALUES (:1, :2, :3)',

43

[1001, 'PROD001', 2]

44

);

45

46

await connection.execute(

47

'UPDATE inventory SET quantity = quantity - :1 WHERE product_id = :2',

48

[2, 'PROD001']

49

);

50

51

// All operations successful - commit

52

await connection.commit();

53

console.log('Transaction committed successfully');

54

55

} catch (error) {

56

// Error occurred - rollback

57

await connection.rollback();

58

console.error('Transaction rolled back:', error.message);

59

throw error;

60

61

} finally {

62

await connection.close();

63

}

64

```

65

66

### Distributed Transactions (TPC/XA)

67

68

Two-Phase Commit protocol support for distributed transactions across multiple databases.

69

70

```javascript { .api }

71

/**

72

* Begins a distributed transaction

73

* @param xid - Transaction identifier

74

* @param flags - Optional transaction flags

75

* @param timeout - Optional timeout in seconds

76

* @returns Promise that resolves when transaction begins

77

*/

78

tpcBegin(xid: string, flags?: number, timeout?: number): Promise<void>;

79

80

/**

81

* Ends a distributed transaction branch

82

* @param xid - Transaction identifier

83

* @param flags - Optional end flags

84

* @returns Promise that resolves when transaction branch ends

85

*/

86

tpcEnd(xid: string, flags?: number): Promise<void>;

87

88

/**

89

* Prepares a distributed transaction for commit

90

* @param xid - Transaction identifier

91

* @returns Promise resolving to boolean indicating if transaction is read-only

92

*/

93

tpcPrepare(xid: string): Promise<boolean>;

94

95

/**

96

* Commits a distributed transaction

97

* @param xid - Transaction identifier

98

* @param onePhase - Whether to use one-phase commit

99

* @returns Promise resolving to boolean indicating success

100

*/

101

tpcCommit(xid: string, onePhase?: boolean): Promise<boolean>;

102

103

/**

104

* Rolls back a distributed transaction

105

* @param xid - Transaction identifier

106

* @returns Promise that resolves when transaction is rolled back

107

*/

108

tpcRollback(xid: string): Promise<void>;

109

110

/**

111

* Forgets a distributed transaction

112

* @param xid - Transaction identifier

113

* @returns Promise that resolves when transaction is forgotten

114

*/

115

tpcForget(xid: string): Promise<void>;

116

117

/**

118

* Recovers distributed transactions

119

* @param flags - Recovery flags

120

* @returns Promise resolving to array of transaction identifiers

121

*/

122

tpcRecover(flags?: number): Promise<string[]>;

123

```

124

125

**Usage Examples:**

126

127

```javascript

128

// Distributed transaction example with two connections

129

const connection1 = await oracledb.getConnection(config1);

130

const connection2 = await oracledb.getConnection(config2);

131

132

const xid = 'distributed-tx-' + Date.now();

133

134

try {

135

// Begin distributed transaction on both connections

136

await connection1.tpcBegin(xid, oracledb.TPC_BEGIN_NEW);

137

await connection2.tpcBegin(xid, oracledb.TPC_BEGIN_NEW);

138

139

// Perform operations on both databases

140

await connection1.execute(

141

'UPDATE accounts SET balance = balance - :amount WHERE account_id = :id',

142

{ amount: 1000, id: 'ACC001' }

143

);

144

145

await connection2.execute(

146

'UPDATE accounts SET balance = balance + :amount WHERE account_id = :id',

147

{ amount: 1000, id: 'ACC002' }

148

);

149

150

// End transaction branches

151

await connection1.tpcEnd(xid);

152

await connection2.tpcEnd(xid);

153

154

// Prepare both branches

155

const readOnly1 = await connection1.tpcPrepare(xid);

156

const readOnly2 = await connection2.tpcPrepare(xid);

157

158

// Commit both branches

159

await connection1.tpcCommit(xid);

160

await connection2.tpcCommit(xid);

161

162

console.log('Distributed transaction committed successfully');

163

164

} catch (error) {

165

// Rollback both branches on error

166

try {

167

await connection1.tpcRollback(xid);

168

await connection2.tpcRollback(xid);

169

} catch (rollbackError) {

170

console.error('Rollback error:', rollbackError);

171

}

172

173

console.error('Distributed transaction failed:', error.message);

174

throw error;

175

176

} finally {

177

await connection1.close();

178

await connection2.close();

179

}

180

```

181

182

### Sessionless Transactions

183

184

Transactions that can span multiple connection sessions.

185

186

```javascript { .api }

187

/**

188

* Begins a sessionless transaction

189

* @param options - Transaction options

190

* @returns Promise resolving to transaction ID

191

*/

192

beginSessionlessTransaction(options?: SessionlessTransactionOptions): Promise<Buffer>;

193

194

/**

195

* Resumes a sessionless transaction

196

* @param transactionId - Transaction ID from beginSessionlessTransaction

197

* @param options - Resume options

198

* @returns Promise that resolves when transaction is resumed

199

*/

200

resumeSessionlessTransaction(transactionId: Buffer, options?: SessionlessTransactionOptions): Promise<void>;

201

202

interface SessionlessTransactionOptions {

203

timeout?: number;

204

}

205

```

206

207

**Usage Examples:**

208

209

```javascript

210

// Begin sessionless transaction

211

const connection1 = await oracledb.getConnection(config);

212

213

const transactionId = await connection1.beginSessionlessTransaction({

214

timeout: 300 // 5 minutes

215

});

216

217

// Perform some operations

218

await connection1.execute(

219

'INSERT INTO temp_data (id, data) VALUES (:1, :2)',

220

[1, 'Transaction data']

221

);

222

223

// Close first connection

224

await connection1.close();

225

226

// Later, resume transaction with different connection

227

const connection2 = await oracledb.getConnection(config);

228

229

await connection2.resumeSessionlessTransaction(transactionId);

230

231

// Continue transaction

232

await connection2.execute(

233

'UPDATE temp_data SET data = :1 WHERE id = :2',

234

['Updated data', 1]

235

);

236

237

// Commit the sessionless transaction

238

await connection2.commit();

239

await connection2.close();

240

241

console.log('Sessionless transaction completed');

242

```

243

244

### Transaction Properties

245

246

Monitor transaction state and properties.

247

248

```javascript { .api }

249

interface Connection {

250

// Transaction state (read-only)

251

transactionInProgress: boolean;

252

}

253

```

254

255

**Usage Examples:**

256

257

```javascript

258

const connection = await oracledb.getConnection(config);

259

260

console.log('Transaction in progress:', connection.transactionInProgress); // false

261

262

// Start a transaction

263

await connection.execute('INSERT INTO test (id) VALUES (1)');

264

265

console.log('Transaction in progress:', connection.transactionInProgress); // true

266

267

// Commit transaction

268

await connection.commit();

269

270

console.log('Transaction in progress:', connection.transactionInProgress); // false

271

```

272

273

### Auto-Commit Configuration

274

275

Configure automatic transaction commitment behavior.

276

277

```javascript { .api }

278

// Global auto-commit setting

279

oracledb.autoCommit: boolean;

280

281

// Per-execute auto-commit

282

interface ExecuteOptions {

283

autoCommit?: boolean;

284

}

285

```

286

287

**Usage Examples:**

288

289

```javascript

290

// Global configuration

291

oracledb.autoCommit = true; // All operations auto-commit

292

293

// Per-operation override

294

await connection.execute(

295

'INSERT INTO logs (message) VALUES (:1)',

296

['Debug message'],

297

{ autoCommit: false } // Don't auto-commit this operation

298

);

299

300

// Batch operations with manual commit

301

oracledb.autoCommit = false;

302

303

await connection.execute('INSERT INTO batch (id) VALUES (1)');

304

await connection.execute('INSERT INTO batch (id) VALUES (2)');

305

await connection.execute('INSERT INTO batch (id) VALUES (3)');

306

307

// Commit all at once

308

await connection.commit();

309

310

// Or use auto-commit for the entire batch

311

await connection.executeMany(

312

'INSERT INTO batch (id, data) VALUES (:1, :2)',

313

[[1, 'data1'], [2, 'data2'], [3, 'data3']],

314

{ autoCommit: true }

315

);

316

```

317

318

### Transaction Constants

319

320

```javascript { .api }

321

// TPC/XA begin flags

322

const TPC_BEGIN_JOIN = 0x00000002;

323

const TPC_BEGIN_NEW = 0x00000001;

324

const TPC_BEGIN_PROMOTE = 0x00000008;

325

const TPC_BEGIN_RESUME = 0x00000004;

326

327

// TPC/XA end flags

328

const TPC_END_NORMAL = 0;

329

const TPC_END_SUSPEND = 0x00100000;

330

```

331

332

**Usage Examples:**

333

334

```javascript

335

// Join existing distributed transaction

336

await connection.tpcBegin(xid, oracledb.TPC_BEGIN_JOIN);

337

338

// Suspend transaction branch

339

await connection.tpcEnd(xid, oracledb.TPC_END_SUSPEND);

340

341

// Resume suspended transaction branch

342

await connection.tpcBegin(xid, oracledb.TPC_BEGIN_RESUME);

343

344

// Normal transaction end

345

await connection.tpcEnd(xid, oracledb.TPC_END_NORMAL);

346

```

347

348

### Error Handling and Recovery

349

350

Common patterns for transaction error handling and recovery.

351

352

**Usage Examples:**

353

354

```javascript

355

// Robust transaction with retry logic

356

async function executeWithRetry(connection, operations, maxRetries = 3) {

357

for (let attempt = 1; attempt <= maxRetries; attempt++) {

358

try {

359

// Execute all operations

360

for (const operation of operations) {

361

await connection.execute(operation.sql, operation.binds);

362

}

363

364

// Commit if all successful

365

await connection.commit();

366

console.log('Transaction completed successfully');

367

return;

368

369

} catch (error) {

370

await connection.rollback();

371

372

if (attempt < maxRetries && isRetryableError(error)) {

373

console.log(`Transaction attempt ${attempt} failed, retrying...`);

374

await new Promise(resolve => setTimeout(resolve, 1000 * attempt));

375

continue;

376

}

377

378

console.error(`Transaction failed after ${attempt} attempts`);

379

throw error;

380

}

381

}

382

}

383

384

function isRetryableError(error) {

385

// Check for specific retryable Oracle errors

386

return error.message.includes('ORA-00060') || // Deadlock

387

error.message.includes('ORA-08177'); // Serialization failure

388

}

389

390

// Deadlock handling

391

try {

392

await connection.execute('UPDATE table1 SET col1 = :1 WHERE id = :2', [val1, id1]);

393

await connection.execute('UPDATE table2 SET col2 = :1 WHERE id = :2', [val2, id2]);

394

await connection.commit();

395

} catch (error) {

396

await connection.rollback();

397

398

if (error.message.includes('ORA-00060')) { // Deadlock detected

399

console.log('Deadlock detected, retrying transaction...');

400

// Implement retry logic with exponential backoff

401

await new Promise(resolve => setTimeout(resolve, Math.random() * 1000));

402

// Retry transaction

403

} else {

404

throw error;

405

}

406

}

407

```