【问题标题】:Using transaction in Spring 3.0 in Spring + JPA + Hibernate在 Spring + JPA + Hibernate 中使用 Spring 3.0 中的事务
【发布时间】:2011-08-22 08:02:31
【问题描述】:

我目前在一个项目中使用 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 类中,以确保此类在 Transaction 中。

在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 事务的事务问题

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

【问题讨论】:

    标签: spring-transactions


    【解决方案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 经验会很有趣。

    【讨论】:

    • 我仍然对何时应该使用 ServiceFacade 设计和模式感到困惑。我读了很多架构,以及许多优点和缺点。开始重构我的项目模式。目前我的日程安排有点紧,也很高兴分享。我继续先重新编码
    • 使用 ServiceFacade 真的取决于你的需要。当您打算开发模块化应用程序时,ServiceFacade 是一个不错的选择。但是由于 Spring 就像一个 bean 容器,它已经为您实现了 ServiceFacade。因此,请参阅我的回答中的建议。
    • 是的。更多关于交易信息显示在这里ibm.com/developerworks/java/library/j-ts1/index.html。我认为这是一个非常好的信息。使用事务时要考虑的许多事项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多