使用普通 JDBC 在 DAO 或服务层中进行事务处理
Posted
技术标签:
【中文标题】使用普通 JDBC 在 DAO 或服务层中进行事务处理【英文标题】:Transaction handling in DAO or Service layer using plain JDBC 【发布时间】:2017-05-19 04:30:21 【问题描述】:假设我有 Account
和 Payment
的课程。
类帐户
public class Account
private Integer id;
private Integer accountHolderId;
private BigDecimal balance;
private Byte status; // 0: account is fine, 1: locked, can't make payments.
// Getters and Setters
类支付
public class Payment
private Integer id;
private BigDecimal amount;
private Integer senderId;
private Integer receiver;
private Integer paymentStatusId;
// Getters and Setters
DAO 层 具有实现 CRUD 方法的 AccountDao
和 PaymentDao
类。下一个是具有AccountService
和PaymentService
类的服务层,它们在DAO 类之上执行附加操作。
由于我正在使用货币/货币,因此我使用的是transactions。我在我的 DAO 课程 中使用它们。
我的DaoFactory
类有一个方法createConnection()
,它为每个特定的DaoFactory(例如mysqlDaoFactory
)返回一个Connection 对象,它使用connection.setAutoCommit(false);
启用了事务功能。所以每次我连接到数据库时,我都会手动使用commit()
和rollback()
方法。
问题
假设我想从一个帐户(发件人)向另一个帐户(收款人)付款。场景如下:
-
检查是否
sender.status == 0
,表示已解锁,可以发送付款。
检查he has more or equals amount of money
是否在他想要发送的余额中。
从他的账户中提取这笔钱。
查看receiver.status == 0
是否解锁,可以收钱。
将金额存入收款人的账户。
将支付状态改为1,即成功。
这个场景告诉我们我们使用了两个 DAO 实例:AccountDao
和 PaymentDao
,并从这些实例中调用方法。当我在PaymentService
中实现这个场景时,它是实现事务的正确方法吗?
【问题讨论】:
这个问题看起来可能会有所帮助:***.com/questions/10792684/… 看起来像 Transaction management with DAOs 的副本。查看答案,看看解决方案有多糟糕,并认真考虑使用 Spring 之类的东西。 【参考方案1】:由于您没有使用某些框架,例如 Spring Transaction(我强烈建议您使用),我建议您执行以下操作:
-
仅使用一个 DAO 类来创建您需要的所有业务流程并在此处使用事务。
在服务层创建连接,并将其作为参数传递给您在业务流程中需要的所有 DAO。我不喜欢这种方式,因为您会将连接控制委托给服务层,也不是数据访问层。
将 JDBC 更改为使用Spring Transaction,它将允许您注释将在服务层中的同一事务中的方法,尽管它们位于不同的 DAO 中。这是可行的,因为 Spring 将控制连接,因此它将通过 DAO 注入相同的连接。看看这个example
更多的是设计偏好的问题,然后哪个是正确的
【讨论】:
这听起来像是一个解决方案,但我也担心在 Service 层使用 Connection 对象。 不要这样做...我不会在我的代码中这样做,我会寻找其他解决方案:p 如何创建一个附加层,不知道如何调用它,但是将在 Service 和 DAO 层之间的层达到我想要的。添加这样的层可以让架构更复杂吗? 另一个调用两个 Daos 并传递连接作为参数的 Dao?这也是一个解决方案以上是关于使用普通 JDBC 在 DAO 或服务层中进行事务处理的主要内容,如果未能解决你的问题,请参考以下文章