no need to use transaction directly