0
# Transactions
1
2
ACID transaction support for file-based databases with manual and context manager interfaces. Transactions provide atomicity, consistency, isolation, and durability for database operations.
3
4
## Capabilities
5
6
### Manual Transaction Management
7
8
Explicit transaction control with begin, commit, and rollback operations.
9
10
```python { .api }
11
def begin(self):
12
"""Begin a new transaction. Only works for file-based databases.
13
Returns True if successful, False for in-memory databases."""
14
...
15
16
def commit(self):
17
"""Commit current transaction. Only works for file-based databases.
18
Returns True if successful, False for in-memory databases."""
19
...
20
21
def rollback(self):
22
"""Rollback current transaction. Only works for file-based databases.
23
Returns True if successful, False for in-memory databases."""
24
...
25
```
26
27
**Usage Example:**
28
29
```python
30
db = unqlite.UnQLite('transactional.db')
31
32
# Manual transaction management
33
try:
34
db.begin()
35
36
# Multiple operations in transaction
37
db['user:1'] = '{"name": "Alice", "balance": 1000}'
38
db['user:2'] = '{"name": "Bob", "balance": 500}'
39
40
# Simulate transfer
41
alice_data = json.loads(db['user:1'])
42
bob_data = json.loads(db['user:2'])
43
44
alice_data['balance'] -= 100
45
bob_data['balance'] += 100
46
47
db['user:1'] = json.dumps(alice_data)
48
db['user:2'] = json.dumps(bob_data)
49
50
# Commit all changes
51
db.commit()
52
print("Transaction committed successfully")
53
54
except Exception as e:
55
# Rollback on error
56
db.rollback()
57
print(f"Transaction rolled back: {e}")
58
```
59
60
### Transaction Context Manager
61
62
Automatic transaction management using Python context managers.
63
64
```python { .api }
65
def transaction(self):
66
"""Create context manager for wrapping a transaction.
67
Returns Transaction object."""
68
...
69
70
class Transaction:
71
def __enter__(self):
72
"""Begin transaction and return self."""
73
...
74
75
def __exit__(self, exc_type, exc_val, exc_tb):
76
"""Commit transaction or rollback on exception."""
77
...
78
```
79
80
**Usage Example:**
81
82
```python
83
db = unqlite.UnQLite('data.db')
84
85
# Automatic transaction management
86
try:
87
with db.transaction():
88
db['config:theme'] = 'dark'
89
db['config:language'] = 'en'
90
db['config:notifications'] = 'true'
91
92
# If any operation fails, entire transaction is rolled back
93
# If all operations succeed, transaction is automatically committed
94
95
except unqlite.UnQLiteError as e:
96
print(f"Transaction failed: {e}")
97
98
# Complex transaction with error handling
99
with db.transaction():
100
# Multiple related operations
101
db['order:123'] = '{"status": "processing", "total": 99.99}'
102
db['inventory:widget'] = '{"stock": 45}' # Decrease stock
103
db['customer:456'] = '{"orders": ["order:123"]}'
104
105
# All operations commit together or all roll back
106
```
107
108
### Autocommit Control
109
110
Control automatic transaction behavior for file-based databases.
111
112
```python { .api }
113
def disable_autocommit(self):
114
"""Disable autocommit for file-based databases.
115
Returns True if successful, False for in-memory databases."""
116
...
117
```
118
119
**Usage Example:**
120
121
```python
122
db = unqlite.UnQLite('manual.db')
123
124
# Disable autocommit for better performance with many operations
125
db.disable_autocommit()
126
127
try:
128
db.begin()
129
130
# Many operations without intermediate commits
131
for i in range(1000):
132
db[f'key{i}'] = f'value{i}'
133
134
# Single commit for all operations
135
db.commit()
136
137
except Exception as e:
138
db.rollback()
139
print(f"Batch operation failed: {e}")
140
```
141
142
### Decorator-Based Transactions
143
144
Automatic transaction wrapping for functions.
145
146
```python { .api }
147
def commit_on_success(self, fn):
148
"""Decorator that wraps function in transaction.
149
Commits on success, rolls back on exception."""
150
...
151
```
152
153
**Usage Example:**
154
155
```python
156
db = unqlite.UnQLite('decorated.db')
157
158
@db.commit_on_success
159
def transfer_funds(from_user, to_user, amount):
160
"""Transfer funds between users with automatic transaction."""
161
from_data = json.loads(db[f'user:{from_user}'])
162
to_data = json.loads(db[f'user:{to_user}'])
163
164
if from_data['balance'] < amount:
165
raise ValueError("Insufficient funds")
166
167
from_data['balance'] -= amount
168
to_data['balance'] += amount
169
170
db[f'user:{from_user}'] = json.dumps(from_data)
171
db[f'user:{to_user}'] = json.dumps(to_data)
172
173
return True
174
175
# Set up test data
176
db['user:alice'] = '{"balance": 1000}'
177
db['user:bob'] = '{"balance": 500}'
178
179
# Use decorated function - automatically transacted
180
try:
181
transfer_funds('alice', 'bob', 100)
182
print("Transfer successful")
183
except ValueError as e:
184
print(f"Transfer failed: {e}")
185
```
186
187
## Transaction Behavior
188
189
### File-Based Databases
190
191
File-based databases support full ACID transactions:
192
193
- **Atomicity**: All operations in a transaction succeed or all fail
194
- **Consistency**: Database remains in valid state after transaction
195
- **Isolation**: Concurrent transactions don't interfere
196
- **Durability**: Committed changes persist after system failure
197
198
```python
199
# File-based database with full transaction support
200
db = unqlite.UnQLite('persistent.db')
201
202
with db.transaction():
203
# All operations are atomic
204
db['critical_data'] = 'important_value'
205
db['backup_data'] = 'backup_value'
206
# Both operations commit together
207
```
208
209
### In-Memory Databases
210
211
In-memory databases have limited transaction support:
212
213
```python
214
# In-memory database
215
db = unqlite.UnQLite(':mem:')
216
217
# Transaction methods return False for in-memory databases
218
result = db.begin() # Returns False
219
result = db.commit() # Returns False
220
result = db.rollback() # Returns False
221
222
# Context manager still works but provides no transactional guarantees
223
with db.transaction():
224
db['key'] = 'value' # Operations execute normally but aren't truly transacted
225
```
226
227
## Error Handling
228
229
Transaction operations can encounter various error conditions:
230
231
```python
232
db = unqlite.UnQLite('transactional.db')
233
234
try:
235
with db.transaction():
236
db['key1'] = 'value1'
237
238
# Simulate error condition
239
if some_error_condition:
240
raise ValueError("Business logic error")
241
242
db['key2'] = 'value2'
243
244
except ValueError as e:
245
print(f"Business error, transaction rolled back: {e}")
246
247
except unqlite.UnQLiteError as e:
248
print(f"Database error: {e}")
249
```
250
251
## Best Practices
252
253
1. **Use context managers** for automatic cleanup and error handling
254
2. **Keep transactions short** to minimize lock contention
255
3. **Batch related operations** in single transactions for consistency
256
4. **Handle exceptions** appropriately with rollback logic
257
5. **Consider disabling autocommit** for bulk operations
258
259
```python
260
db = unqlite.UnQLite('optimized.db')
261
262
# Efficient bulk loading
263
db.disable_autocommit()
264
265
try:
266
with db.transaction():
267
# Process large dataset in single transaction
268
for record in large_dataset:
269
db[record['id']] = json.dumps(record)
270
271
# Single commit for entire batch
272
273
except Exception as e:
274
print(f"Bulk load failed: {e}")
275
# Automatic rollback via context manager
276
```