factor out transaction