我可以把mysql事务数据库逻辑放在哪一层?
我可以把mysql事务数据库逻辑放在哪一层?
基本上,我有两个服务,每个服务处理我项目中的每个持久对象的方法,这些服务保存一些方法,终端(Google)将调用这些方法来执行某些操作。
我使用Google Could Endpoints + Mysql Cloud + Hibernate。
两个持久对象:
@Entity public class Device { ... } @Entity public class User { ... }
每个持久对象的服务:
public class DeviceService { Device getDevice(Long devId){ return new Dao().getById(devId, Device.class); } void allocateDevice(Long userId){ User u = new UserService().getUser(userId); ... 做一些操作 } } public class UserService { User getUser(Long userId){ return new Dao().getById(userId, User.class); } }
每个对象的终端:
public class DeviceEndpoint { @ApiMethod( name = "device.get", path = "device/{devId}", httpMethod = ApiMethod.HttpMethod.GET ) Device getDevice(Long devId){ MyEntityManager em = new MyEntityManager(); try { em.getTransaction().begin(); new DeviceService().getDevice(devId); em.getTransaction().commit(); }finally { em.cleanup(); //自定义方法也可以回滚 } return device; } @ApiMethod( name = "device.allocate", path = "device/{userId}/allocate", httpMethod = ApiMethod.HttpMethod.GET ) void allocateDevice(Long deviceId){ MyEntityManager em = new MyEntityManager(); try { em.getTransaction().begin(); new DeviceService().allocateDevice(userId); em.getTransaction().commit(); }finally { em.cleanup(); //自定义方法也可以回滚 } } }
我想知道我应该把数据库事务逻辑(begin、commit、rollback)放在哪里。
- Dao层
最初,我把它插入到Dao类中,但是每次查询/插入/更新时,我都需要打开和关闭连接,当我需要使用多个CRUD时,我进行了多次打开/关闭连接,这样非常昂贵和耗时。
例如:在一个终端请求中,我想从数据库中获取一些对象并进行更新。两个操作和两个打开/关闭连接。
- 终端层(例如)
其次,我将打开/关闭逻辑放在终端方法中(如上所示),但他们说(我的同事)这不是一个好的模式,在这一层中开始和提交事务不是一个好主意,然后他们建议采用第三种选择。
- 服务层
将逻辑(begin/commit/rollback)放入服务层中的每个方法中,我尝试过,但是一些方法调用了另一个方法,而最后一个方法也打开和关闭连接,所以当第二个方法返回时,事务已经关闭了。
请告诉我是否遗漏了一些重要信息。
通常情况下,将mysql事务数据库逻辑放在服务层(Service Layer)中,因为该层提供了操作在数据访问对象(DAO Layer)发送和返回的数据的逻辑。但是,你也可以将它们捆绑在同一个模块中。
关于"我尝试过,但是有些方法会调用另一个方法,而最后一个方法会打开和关闭连接,所以当第二个方法返回时,事务已经关闭了"的评论很有意思。我不确定你是如何管理连接的,但你可能需要重新考虑在事务完成之前关闭连接的问题,你可以考虑使用Hibernate的HibernateTransactionManager。
在问题代码的端点中,你可以看到我是如何管理连接的示例。如果我可以使用注解就好了,但我不能使用Spring模块,因为我相信这个注解只在最后一个方法上处理打开和关闭的次数。例如:两个方法都有这个注解,第一个方法调用了第二个方法,这个注解会正确处理谁将适当地打开和关闭事务,但这只是我的感觉。
所以,你可以将mysql事务数据库逻辑放在服务层中,并确保在事务完成之前不要关闭连接。如果你无法使用Spring模块的注解,你可以考虑其他方法来处理事务的打开和关闭。