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

Posted

技术标签:

【中文标题】mysql事务数据库逻辑可以放在哪一层?【英文标题】:Which layer can I put the mysql transaction database logic? 【发布时间】:2018-01-02 02:44:51 【问题描述】:

基本上,我有两个服务,每个服务都处理我在项目中拥有的每个持久对象的方法,这些服务包含一些端点(Google)将调用以执行某些操作的方法。 我正在使用 Google Can Endpoints + mysql Cloud + Hibernate。

两个采购订单

@Entity
public class Device 
    ...


@Entity
public class User 
    ...

每个 PO 的服务

public class DeviceService 
    Device getDevice(Long devId)
        return new Dao().getById(devId, Device.class);
    
    void allocateDevice(Long userId)
        User u = new UserService().getUser(userId);
        ... do stuff
    


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(); //custom method to rollback also
        
        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(); //custom method to rollback also
        
    

我想知道我将数据库事务逻辑放在哪里(开始、提交、回滚)。

    道层

首先我插入了 Dao 类,但是每次查询/插入/更新我都必须打开和关闭连接,当我不得不使用多个 CRUD 时,我做了几个打开/关闭连接它既昂贵又延迟。 示例:在一个端点请求中,我想从 db 获取一些对象并进行更新。两个操作和两个打开/关闭连接。

    端点层(作为示例)

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

    服务层

将该逻辑(开始/提交/回滚)放入服务层,在每个方法中,我都尝试过,但是,有些方法调用另一个,最后也打开和关闭连接,所以当第二个方法返回时,事务关闭.

请告诉我缺少一些重要信息的情况。

【问题讨论】:

首先,不能在服务层放任何逻辑。它应该几乎不会告诉您该对象实际上做了什么,正如Oracle doc 所说:使用数据访问对象 (DAO) 来抽象和封装对数据源的所有访问。 DAO 管理与数据源的连接以获取和存储数据。您可以添加一个业务模型层并在中添加逻辑 正如我在第一个选项中提到的那样,DAO 中的逻辑并没有避免,例如,当我想在数据库中为一个请求执行一些操作时,它已经打开并且犯了几次。我需要避免这种行为,因为它非常昂贵,在端点层上似乎比其他层要快。 【参考方案1】:

通常这种类型的操作在服务层中执行,因为该层提供逻辑来操作发送到 DAO 层和从 DAO 层传出的数据——也就是说,您可以将它们捆绑到同一个模块中。

评论“我试过了,但是,有些方法调用了另一个,最后也打开和关闭了连接,所以当第二个方法返回时,事务就关闭了。”有趣;我不确定你是如何管理你的连接的;但是如果您的连接在事务完成之前被关闭,您可能希望/需要重新访问 - 您可能需要查看 Hibernates HibernateTransactionManager

Where should "@Transactional" be place Service Layer or DAO

【讨论】:

我如何管理连接的示例,您可以在问题代码和 Endpoint 中看到。如果我可以使用 @Transactional 注释会很棒,但我不能使用 Spring 模块,因为我相信这个注释可以处理你在最终方法上尝试打开和关闭的次数。示例:两种方法都有那个注解,第一个叫第二个,这个注解处理谁将正确打开和关闭事务,但这只是我的感觉。

以上是关于mysql事务数据库逻辑可以放在哪一层?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql逻辑架构事务并发控制

Mysql逻辑架构事务并发控制

您将 REST api 放在哪一层?

mysql数据库事务

mysql存储引擎

mysql事务与多版本并发控制