use transaction to prevent dangling keys