1

我目前在一个项目中使用 Spring + JPA + hibernate。然后我在模型 dan DAO 实现中决定我的设计模式。我的所有交易目的类都有一个摘要。每个执行单个更新/创建/删除任务的类(作为服务)都必须继承自这个抽象类。

public class GlobalAbstractTransaction {
 public abstract void validation(DTO param);
 public abstract void process(DTO param);
 public void execute(DTO param){
     validation(param);
     process(param);
 }
}

然后我有另一个类(上面类的子类)

@Service
@Transactional //using spring annotation for transactional support
public class SomeTransaction extends GlobalAbstractTransaction
                           implements ITransaction {
     //implements abstract method
     public void validation(DTO param){
     }
     //implements abstract method
     public void process(DTO param){
     }
}

BusinessTransaction 是一个具有一个方法的接口

public interface ITransaction {
     public execute(DTO param);
}

请注意,我将@Transactional(使用默认 Propagation.REQUIRED)放在 SomeTransaction 类中,希望确保该类在事务中。

在 IntegrationTest 中使用时

@Autowired //default by name
ITransaction someTransaction;

@Test
public void testInsert(){
       DTO someDTO = new DTO(); 
       //apply value for DTO
       someTransaction.execute(someDTO);
}

结果是没有交易发生。并且仅执行将数据插入数据库任务的 someTransaction.execute 运行不佳。

然后我将 @Transactional 注释从 SomeTransaction 移动到 GlobalAbstractTransaction,这样代码就会像这样。

修改后的 GlobalAbstractTransaction

public class GlobalAbstractTransaction {
 public abstract void validation(DTO param);
 public abstract void process(DTO param);

 @Transactional //added here
 public void execute(DTO param){
     validation(param);
     process(param);
 }
}

修改了 SomeTransaction

@Service
//transactional annotation removed
public class SomeTransaction extends GlobalAbstractTransaction
                           implements ITransaction {
     //implements abstract method
     public void validation(DTO param){
     }
     //implements abstract method
     public void process(DTO param){
     }
}

然后,测试工作,将数据插入数据库。

  1. 任何人都可以解释为什么会这样。我无法在 SomeTransaction.execute 中添加 @Transactional,因为它已经在 GlobalAbstractTransaction 中定义。我可以添加@Transactional 添加类级别吗?
  2. SomeTransaction 被计划为服务,在服务中我使用自动装配自动装配了 DAO 实现(我没有在 DAO 级别放置任何 @Transactional),这是大多数人推荐的。我只是将DAO 实现注释为@Repository,将服务类注释为@Service。(注意,在我的服务中只执行一项任务,InsertingService、UpdatingService、DeletingService 将分为三个类)。我计划为 Service Facade 添加另一层([http://java.dzone.com/articles/jpa-implementation-patterns-3][1]),请参阅链接以供参考。所以我创建了一个类

    公共类 ServiceFacadeBean { public void executeTransaction(String name){

    } }

我打算在这样的应用程序中使用。

 @Autowired //injected using Spring autowiring
 ServiceFacadeBean serviceFacadeBean;

 serviceFacadeBean.execute("com.mycompany.SomeTransaction");

在执行的执行中,我想使用反射使用“com.mycompany.SomeTransaction”来创建实例。但我总是得到NullPointerException

 Class clazz = Class.forName("com.mycompany.SomeTransaction");

 clazz.newInstance() <--- get null

而且我打算使用 1 个服务类,只执行 1 个事务任务,例如插入数据库。放置@Transactional的最佳实践是什么,或者任何人都有很好的链接,可以很好地解释使用Spring事务的事务问题

任何人都有这方面的经验,或者有更好的设计模式解决方案吗?谢谢

4

1 回答 1

1

我与雅加达的一家软件公司有联系,该公司使用的架构与您正在实施的架构完全相同。它们具有执行单个任务并接收单个 DTO 作为参数的 BusinessTransaction。bean 也使用 Spring 3.0 进行管理,持久性也使用 JPA 2 和 Hibernate 完成。关于你的 NullPointerExecution 你不应该使用反射也不应该使用你的 ServiceFacadeBean 而是让你的 BusinessTransactions 像这样命名 bean:

@Service("SomeTransaction")
//transactional annotation removed
public class SomeTransaction extends AbstractTransaction
                       implements ITransaction {
....
}

每当您需要执行此事务时,您都会像这样注入它:

@Autowired
@Qualifier("SomeTransaction")
ITransaction someTransaction;

public doSomething() {
    DTO dto = new DTO();
    dto.putString("id", "948392943");
    someTransaction.execute(dto);
}

PS:我现在在雅加达旅游,有什么联系方式吗?直接与您分享 IT 经验会非常有趣。

于 2011-05-11T10:10:33.057 回答