EnglishРусский Map

transactioncheck

title
transactioncheck
type
toolbox
summary
Go-линтер, находящий вызовы БД через внешний репозиторий вместо дескриптора транзакции
tags
golang, static-analysis, databases
language
Go
license
MIT
created
2026-04-15
updated
2026-09-01
lang
ru
translation_of
transactioncheck
source_updated
2026-09-01
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

Go-линтер, обнаруживающий операции с базой данных, которые утекают за границы транзакции. Написан на базе go-analysis-framework после того, как автор выкатил баг с транзакцией в продакшен - эта история и появление линтера описаны в go-transaction-linter.

Что он находит

В кодовых базах, где транзакции работают через callback'и с паттерном репозитория:

return s.repo.Transaction(ctx, func(tx models.Repo) error {
    user, err := s.repo.GetUser(ctx, userID) // FLAGGED: uses s.repo, not tx
    return tx.SaveUser(ctx, user)
})

Линтер помечает использование внешнего репозитория (s.repo) внутри callback'ов транзакции, где вместо этого должен использоваться параметр транзакции (tx).

Два типа нарушений:

  • Прямые вызовы методов внешнего репозитория
  • Передача внешнего репозитория во вспомогательные функции вместо tx

Как это работает

  1. Обход AST с фильтрацией по узлам *ast.CallExpr
  2. Поиск вызовов метода Transaction у интерфейсов репозитория
  3. Захват параметра callback'а tx как types.Object
  4. Сканирование тела callback'а на предмет обращений к внешнему репозиторию
  5. Рекурсивный анализ вспомогательных функций, принимающих tx

Сравнение через types.Object корректно обрабатывает затенение переменных: два идентификатора с одним и тем же объектом указывают на одну и ту же переменную.

Использование

Запуск отдельно:

go install github.com/leonhfr/transactioncheck/cmd/transactioncheck@latest
transactioncheck ./...

Или через задачу mise:

[tasks.transactioncheck]
run = 'bin/transactioncheck ./...'

Тестирование

Использует analysistest с комментариями // want:

_ = s.repo.GetUser( // want "using non-transaction repo..."
    ctx, "123",
)

Ограничения

  • Требует единообразного именования интерфейсов репозиториев (настраивается)
  • Отслеживает нарушения только внутри одного пакета (межпакетный анализ отсутствует)
  • Рекурсивный анализ может пропускать нарушения при вызовах через интерфейсы

Repo: https://github.com/leonhfr/transactioncheck