如何为多个 Dao 实现事务管理器
How to implement Transaction Manager for multiple Dao
我正在编写一个遵循 MVC 模式的 Java 应用程序,其抽象程度足以让后端连接到一个 Sql 和一个 NoSql 数据库。我有 4 个模型 类 和 4 个 DAO 接口。每个 DAO 以两种方式实现,一种用于 sql,一种用于 mongodb。我想添加一个事务管理器以在原子事务中执行数据库操作:问题是这些操作涉及可变数量的 DAO,我不知道如何使用多个 Dao 来实现管理器。 我没有用Spring也不愿意加
我有以下想法,但每个想法都有我不确定的地方:
- 使接口 `MyDao_X` 扩展另一个接口 `GenericDao` 并使用 TransactionCode 中的最后一个接口。这样我就不知道在 `TransactionManagerMysql`
中实例化哪个 Dao
- 将函数扩展为一个 N 函数,它可以接受 N 个输入并产生一个输出。在本例中 N = 4,所以我总是可以实例化所有 DAO。这里的疑问如下:我不知道该怎么做,我正在关注 TDD,所以我应该弄清楚如何测试这个扩展。而且,每次实例化 4 Dao 对我来说似乎不是很有效,只是因为我不知道我需要多少或类型。此外,如果 Dao 的数量随时间变化,我将被迫修改服务层中的所有函数以适应 lambdas
的输入数量
如果只有一把刀我会怎么做
public interface TransactionManager {
<T> T executeTransaction(TransactionCode<T> code);
}
@FunctionalInterface
public interface TransactionCode<T> extends Function<MyDAO, T> {
}
public class ServiceLayer {
private TransactionManager transactionManager;
public ServiceLayer(TransactionManager manager) {
transactionManager = manager;
}
public void doSomethingInTransaction() {
transactionManager.executeTransaction((myDao) -> {
myDao.doSomething();
return null;
});
}
}
public class TransactionManagerMysql implements TransactionManager {
private EntityManager entityManager;
public TransactionManagerMysql(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public <T> T executeTransaction(TransactionCode<T> code) {
try {
entityManager.getTransaction().begin();
T result = code.apply(new MyDaoSQL(entityManager));
entityManager.getTransaction().commit();
return result;
} catch (Exception e) {
entityManager.getTransaction().rollback();
}
}
}
我确定我必须将 Function
扩展为自定义 N-Function
以便能够传递多个输入参数(因为我的老师就是这样解释的)。好吧,我发现我不需要使用 Function
,甚至在 single-input 场景中也不需要。这里扩展 Function
的唯一目的是从 ServiceLayer
调用它的方法 apply()
。我可以只定义一个具有足够数量输入的方法,而不是概括为 N-Function
。要回答我的问题就足以重写 TransactionCode
如下:
@FunctionalInterface
public interface TransactionCode<T> {
T apply(MyDaoA daoA, MyDaoB daoB, MyDaoC daoC, MyDaoD daoD);
}
我正在编写一个遵循 MVC 模式的 Java 应用程序,其抽象程度足以让后端连接到一个 Sql 和一个 NoSql 数据库。我有 4 个模型 类 和 4 个 DAO 接口。每个 DAO 以两种方式实现,一种用于 sql,一种用于 mongodb。我想添加一个事务管理器以在原子事务中执行数据库操作:问题是这些操作涉及可变数量的 DAO,我不知道如何使用多个 Dao 来实现管理器。 我没有用Spring也不愿意加
我有以下想法,但每个想法都有我不确定的地方:
- 使接口 `MyDao_X` 扩展另一个接口 `GenericDao` 并使用 TransactionCode 中的最后一个接口。这样我就不知道在 `TransactionManagerMysql` 中实例化哪个 Dao
- 将函数扩展为一个 N 函数,它可以接受 N 个输入并产生一个输出。在本例中 N = 4,所以我总是可以实例化所有 DAO。这里的疑问如下:我不知道该怎么做,我正在关注 TDD,所以我应该弄清楚如何测试这个扩展。而且,每次实例化 4 Dao 对我来说似乎不是很有效,只是因为我不知道我需要多少或类型。此外,如果 Dao 的数量随时间变化,我将被迫修改服务层中的所有函数以适应 lambdas 的输入数量
如果只有一把刀我会怎么做
public interface TransactionManager {
<T> T executeTransaction(TransactionCode<T> code);
}
@FunctionalInterface
public interface TransactionCode<T> extends Function<MyDAO, T> {
}
public class ServiceLayer {
private TransactionManager transactionManager;
public ServiceLayer(TransactionManager manager) {
transactionManager = manager;
}
public void doSomethingInTransaction() {
transactionManager.executeTransaction((myDao) -> {
myDao.doSomething();
return null;
});
}
}
public class TransactionManagerMysql implements TransactionManager {
private EntityManager entityManager;
public TransactionManagerMysql(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public <T> T executeTransaction(TransactionCode<T> code) {
try {
entityManager.getTransaction().begin();
T result = code.apply(new MyDaoSQL(entityManager));
entityManager.getTransaction().commit();
return result;
} catch (Exception e) {
entityManager.getTransaction().rollback();
}
}
}
我确定我必须将 Function
扩展为自定义 N-Function
以便能够传递多个输入参数(因为我的老师就是这样解释的)。好吧,我发现我不需要使用 Function
,甚至在 single-input 场景中也不需要。这里扩展 Function
的唯一目的是从 ServiceLayer
调用它的方法 apply()
。我可以只定义一个具有足够数量输入的方法,而不是概括为 N-Function
。要回答我的问题就足以重写 TransactionCode
如下:
@FunctionalInterface
public interface TransactionCode<T> {
T apply(MyDaoA daoA, MyDaoB daoB, MyDaoC daoC, MyDaoD daoD);
}