我可以把mysql事务数据库逻辑放在哪一层?

19 浏览
0 Comments

我可以把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)放在哪里。

  1. Dao层

最初,我把它插入到Dao类中,但是每次查询/插入/更新时,我都需要打开和关闭连接,当我需要使用多个CRUD时,我进行了多次打开/关闭连接,这样非常昂贵和耗时。

例如:在一个终端请求中,我想从数据库中获取一些对象并进行更新。两个操作和两个打开/关闭连接。

  1. 终端层(例如)

其次,我将打开/关闭逻辑放在终端方法中(如上所示),但他们说(我的同事)这不是一个好的模式,在这一层中开始和提交事务不是一个好主意,然后他们建议采用第三种选择。

  1. 服务层

将逻辑(begin/commit/rollback)放入服务层中的每个方法中,我尝试过,但是一些方法调用了另一个方法,而最后一个方法也打开和关闭连接,所以当第二个方法返回时,事务已经关闭了。

请告诉我是否遗漏了一些重要信息。

0
0 Comments

通常情况下,将mysql事务数据库逻辑放在服务层(Service Layer)中,因为该层提供了操作在数据访问对象(DAO Layer)发送和返回的数据的逻辑。但是,你也可以将它们捆绑在同一个模块中。

关于"我尝试过,但是有些方法会调用另一个方法,而最后一个方法会打开和关闭连接,所以当第二个方法返回时,事务已经关闭了"的评论很有意思。我不确定你是如何管理连接的,但你可能需要重新考虑在事务完成之前关闭连接的问题,你可以考虑使用Hibernate的HibernateTransactionManager。

在问题代码的端点中,你可以看到我是如何管理连接的示例。如果我可以使用注解就好了,但我不能使用Spring模块,因为我相信这个注解只在最后一个方法上处理打开和关闭的次数。例如:两个方法都有这个注解,第一个方法调用了第二个方法,这个注解会正确处理谁将适当地打开和关闭事务,但这只是我的感觉。

所以,你可以将mysql事务数据库逻辑放在服务层中,并确保在事务完成之前不要关闭连接。如果你无法使用Spring模块的注解,你可以考虑其他方法来处理事务的打开和关闭。

0