transactions
Skill4 starsChanged 4 months agoMITView on GitHub
Use SQL transactions correctly — ACID guarantees, isolation levels, deadlock handling with retries, and savepoints — so multi-statement writes stay consistent under concurrency. Use when the user hits InnoDB deadlocks or deadlock errors under load, lost updates, or inconsistent reads, and wants to handle and retry them when multiple requests write the same rows concurrently; the user needs to pick or reason about an isolation level (READ COMMITTED, REPEATABLE READ, SERIALIZABLE), use a savepoint for partial rollback, or fix a phantom/non-repeatable read; the user performs multiple related writes (transfer funds, create order plus line items) that must commit together or not at all. Keywords: transactions, transaction, acid, isolation-levels, deadlock, deadlocks, retry, innodb, savepoints, savepoint, rollback, mysql, sql, database, concurrency, performance.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- ffsshhttiikk/opencode-agents-skillstheir own version, first seen Feb 28, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- ffsshhttiikk/opencode-agents-skills★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository119 other files it gives its agents.
- strategy-bitrix-d7-incrementalSkill
- strategy-explicit-over-magicSkill
- strategy-framework-conventionsSkill
- strategy-legacy-safe-editsSkill
- strategy-minimal-diffSkill
- strategy-no-untested-refactorSkill
- strategy-preserve-public-apiSkill
- strategy-readonly-immutabilitySkill
- strategy-security-firstSkill
- strategy-test-drivenSkill
- openapiSkill
- paginationSkill
- rest-designSkill
- versioningSkill
- cqrsSkill
- dependency-inversionSkill
- hexagonalSkill
- repository-patternSkill
- service-layerSkill
- bitrixSkill
- findings-reportSkill
- laravelSkill
- performanceSkill
- phpSkill
- project-analysisSkill
- refactoringSkill
- roi-prioritizationSkill
- securitySkill
- stack-detectionSkill
- cache-layersSkill
- component-engineSkill
- d7-eventsSkill
- d7-loaderSkill
- d7-orm-queriesSkill
- iblock-elementsSkill
- kernel-main-moduleSkill
- localizationSkill
- controllersSkill
- ormSkill
- validationSkill
- controllersSkill
- query-builderSkill
- routingSkill
- autoload-psr4Skill
- dependency-managementSkill
- scriptsSkill
- connection-poolingSkill
- mysql-indexingSkill
- redisSkill
- ci-github-actionsSkill
- deployment-strategiesSkill
- docker-phpSkill
- env-configSkill
- associationsSkill
- entities-mappingSkill
- orm-basicsSkill
- entity-apiSkill
- module-developmentSkill
- routing-controllersSkill
- formsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 4 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 71
Do not assume transactional semantics on MyISAM tables, DDL statements, or stores without ACID support — BEGIN/ROLLBACK will silently do …
- Distinctive: line 73
Do not wrap one standalone INSERT/UPDATE in BEGIN/COMMIT — a single statement is already atomic under autocommit.
- Very specific: line 90
Start the transaction, then SELECT ...
- Distinctive: line 99
When a transaction touches several rows or tables, always lock them in the same deterministic order (for example, ascending primary key) …
- Distinctive: line 101
Default to READ COMMITTED or REPEATABLE READ for OLTP.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- generated: do not edit — source: knowledge/atoms/databases/transactions/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->Database Transactions
When to use
- The user hits InnoDB deadlocks or deadlock errors under load, lost updates, or inconsistent reads, and wants to handle and retry them when multiple requests write the same rows concurrently.
- The user needs to pick or reason about an isolation level (READ COMMITTED, REPEATABLE READ, SERIALIZABLE), use a savepoint for partial rollback, or fix a phantom/non-repeatable read.
- The user performs multiple related writes (transfer funds, create order plus line items) that must commit together or not at all.
When NOT to use
- Do not assume transactional semantics on MyISAM tables, DDL statements, or stores without ACID support — BEGIN/ROLLBACK will silently do nothing there.
- Do not wrap one standalone INSERT/UPDATE in BEGIN/COMMIT — a single statement is already atomic under autocommit.
Core guidance
- Keep transactions short and do no I/O inside them — Open the transaction as late as possible, do only the required DB writes, and commit immediately. Never make HTTP calls, send email, or sleep while a transaction holds locks.
- Retry deadlock victims with backoff, do not swallow them — Catch the deadlock/lock-wait error (MySQL 1213/1205), roll back, and retry the whole transaction a bounded number of times with small backoff. Only give up after the retry budget is exhausted.
- Guarantee rollback on every failure path — Run the transaction inside try/catch (or a framework closure): commit on success, roll back in the catch, and rethrow. Never leave a path where an exception escapes with the transaction still open.
Quick recipe
- Start the transaction, then
SELECT ... FOR UPDATEthe exact rows you will change so concurrent writers block instead of racing. (verify: A second connection's write to the same rows waits until this transaction commits.) - Perform the DML, then commit. Wrap the block in try/catch so any exception triggers a rollback and rethrow, leaving no open transaction behind. (verify: On a thrown error the row values are unchanged and no locks remain held.)
- Enclose steps 1–2 in a retry loop that catches deadlock/lock-wait errors, rolls back, backs off briefly, and retries up to a small fixed limit before failing. (verify: A forced deadlock is retried and eventually succeeds, or fails cleanly after the retry budget.)
Best practices
- When a transaction touches several rows or tables, always lock them in the same deterministic order (for example, ascending primary key) across all code paths
- Default to READ COMMITTED or REPEATABLE READ for OLTP; raise to SERIALIZABLE only for invariants that must never see phantoms, and use `SELECT ..
- Wrap an optional sub-step in `SAVEPOINT sp; ..
Anti-patterns
| Anti-pattern | Why it fails | Do instead |
| Read-modify-write without locking loses updates | The gap between read and write is a race window; without a lock the last writer silently wins and updates are lost. | Use an atomic UPDATE ... SET balance = balance + ?, or SELECT ... FOR UPDATE<br>inside the transaction to lock the row before modifying it. |
| SERIALIZABLE on every query as a blanket safety net | The strictest isolation serializes access and cripples throughput when most queries never needed it. | Keep a sensible default (READ COMMITTED / REPEATABLE READ) and reach for<br>row-level FOR UPDATE locks or SERIALIZABLE only on the specific invariant-critical path. |
| One giant transaction wrapping a whole batch loop | A huge transaction bloats the undo log, holds locks for minutes, and makes retries all-or-nothing. | Commit in bounded chunks (e.g. every 1k rows) so locks release, undo stays<br>small, and a failure only costs the current chunk. |
See references/anti-patterns.md.
Common mistakes
- DDL inside a transaction triggers an implicit commit — Running a
CREATE TABLE,ALTER TABLE, orTRUNCATEinside what looks like a transaction silently commits everything before it, so a later ROLLBACK cannot undo the earlier writes. Fix: Keep schema changes out of data transactions; run migrations separately, and never mix DDL with the DML you intend to roll back. - External calls inside a transaction hold locks for seconds — Making an HTTP request, calling a payment API, or dispatching a job while a transaction is open keeps its row locks held for the entire network round-trip. Fix: Do the DB writes and commit first, then perform external work; if the external result must persist, use an outbox row committed in the same transaction and processed afterward.
- A second BEGIN silently commits the first transaction — Issuing
START TRANSACTIONwhile one is already open commits the outer transaction instead of nesting, so the two blocks are not atomic together. Fix: Use SAVEPOINT for inner units of work, or rely on a framework's transaction helper that tracks depth and emits savepoints instead of raw BEGIN. - Catching a deadlock and continuing corrupts state — Catching a deadlock exception and proceeding as if the write succeeded leaves the transaction already rolled back by the engine, so later statements run outside any transaction. Fix: On a deadlock, roll back explicitly, then retry the whole unit of work from the start with backoff, or fail loudly after the retry budget.
Version notes
- MySQL 8 adds atomic DDL, but DML still cannot span it (PHP >=7.4) — MySQL 8.0 makes individual DDL statements crash-safe (atomic DDL), but DDL still causes an implicit commit of your open transaction; the InnoDB default isolation level remains REPEATABLE READ across 5.7 and 8.0.
Security
- Guard money-moving transactions against replay — For financial or state-changing operations, lock the row (
FOR UPDATE) and enforce an idempotency key or a unique constraint inside the same transaction so a retried or replayed request cannot double-apply.
Testing
- Activation and decision behavior are verified in
eval/scenarios/databases/transactions.yaml.
Additional resources
- references/anti-patterns.md
- references/core.md
- references/examples.md
- references/pitfalls.md
- references/recipes.md
- references/version-differences.md
Knowledge graph
Related: databases/connection-pooling, databases/mysql-indexing
<!-- graph-fragment: graph/fragments/databases/transactions.yaml -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

