Transaction-Safe Migrations with Redis WATCH/MULTI/EXEC
December 17, 2025 · Eden Team
Tags: release
Redis transactions using WATCH/MULTI/EXEC provide optimistic locking for atomic operations. During migrations, these transactions must execute entirely on a single Redis instance—splitting commands between old and new databases would corrupt your data.
Eden v0.12.0 introduces connection pinning that keeps transactions safe during migrations.
The Problem
Consider this common Redis pattern:
# Watch a key for changes
redis.watch('user:123:balance')
# Read current value
balance = int(redis.get('user:123:balance'))
# Start transaction
pipe = redis.pipeline()
pipe.multi()
pipe.set('user:123:balance', balance - 100)
pipe.set('user:123:last_transaction', now())
pipe.execute() # Executes atomically, or aborts if balance changedIf WATCH goes to the old database but MULTI/EXEC goes to the new one, the optimistic lock is meaningless. You've lost atomicity.
Connection Pinning
Eden now tracks transaction state per connection:
- WATCH received → Pin this connection to its current target
- MULTI received → Confirm pinning, begin queueing commands
- EXEC received → Execute atomically, release pin
- DISCARD received → Abort transaction, release pin
During the pinned period, even if migration routing rules change, this connection stays on its original database.
Works with All Routing Strategies
Canary deployments — A connection that starts a transaction during the 10% canary window stays on the new database for the entire transaction.
Dual-write migrations — Transactions are NOT replicated. They execute on the authoritative database only. Replaying a WATCH-based transaction on both databases would likely cause one to abort due to version conflicts.
Custom Query Patterns
v0.12.0 also adds custom template registration to the request analyzer:
analyzer.register_template(
"rate_limiter",
TemplateConfig {
pattern: "INCR rate:{user_id}:*",
extract_fields: vec!["user_id"],
suggested_ttl: Some(Duration::from_secs(60)),
}
);The analyzer now identifies your application-specific query patterns and suggests optimizations based on actual usage.