问题描述
我在Spring中有rest风格的控制器.在控制器中,我注入了dao接口.从控制器我保留数据.换句话说,我喜欢REST Web服务.人们向我发送数据,然后我继续查看.
I have rest style controller in Spring. In controller I have injected dao interfaces. From controller I persist data. In the other words, I have like REST web service. people sends me data, and I persits it.
/**
* Payment rest controller which receives
* JSON of data
*/
@Controller
@RequestMapping("/data")
public class PaymentTransaction {
@Autowired
private TestDao dao;
@RequestMapping(value = "/test", method = RequestMethod.POST)
@ResponseBody()
public String test(HttpServletRequest request) {
...
}
目前,我在Dao类中具有@transaction批注.例如:
At the moment I have @transaction annotation in Dao classes. For instance:
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public interface TestDao {
@Transactional(propagation = Propagation.REQUIRED)
public void first();
}
我已经读到这是非常糟糕的样式.在stackoverflow上使用此答案,这里是解释和示例,为什么这样做很糟糕-我们也不能在DAO和控制器中添加此批注.我们必须将其添加到服务层.
I have read that this is very bad style. Using this answer at stackoverflow , here is explain and examples why is this bad - we must not add this annotation in DAO and in controller too. We must add it in service layer.
但是我不明白什么是服务层?还是在哪里?我没有这样的东西.我应该在哪里写@Transactional注释?
But I don't understand what is the service layer? Or where is it? I do not have anything like this.where should I write @Transactional annotation?
最诚挚的问候,
推荐答案
根据引用帖子,您应该设计您的类以某种方式(而不是伪代码):
According to the cited post, you should design your classes somehow like this (rather pseudocode):
-
控制器(负责处理客户的请求/响应)
controller (responsible for handling clients' requests/responses)
@Controller
@RequestMapping("/data")
public class TestREST {
@Autowired
private TestService service;
public void storePayment(PaymentDTO dto) {
service.storePayment(dto); //request from a client
}
public PaymentDTO getPayment(int paymentId) {
return service.getPayment(paymentId); //response to a client
}
}
服务层(也称为业务层,负责业务逻辑-知道如何处理传入的消息,但不知道它们来自何处) .
service layer (also called business layer, responsible for business logic - knows what to do with incoming messages, but does not know where they come from).
public class TestServiceImpl {
@Autowired
private TestDao dao;
@Transactional(propagation=Propagation.REQUIRED) //force transaction
public void storePayment(PaymentDTO paymentDto) {
// transform dto -> entity
dao.storePayment(paymentEntity); //read-write hence transaction is on
}
@Transactional(propagation=Propagation.NOT_SUPPORTED) //avoid transaction
public Payment getPayment(int paymentId) {
return dao.findPayment(paymentId); //read-only hence no transaction
}
}
数据访问层(也称为持久层,负责访问数据库-知道如何使用实体模型/ORM,但对上层一无所知服务层)
data access layer (also called persistence layer, responsible for accessing database - knows how to use entity model / ORM, does not know anything about the upper service layer)
public class TestDAOImpl {
@PersistenceContext
private EntityManager em;
public void storePayment(PaymentEntity paymentEntity) {
em.persist(paymentEntity);
}
public PaymentEntity getPayment(int paymentId) {
return em.find(PaymentEntity.class, paymentId);
}
}
通过这种方法,您会在帖子中提到关注点分离.另一方面,这种方法(业务层与数据访问层)受到亚当·比恩(Adam Bien)在其博客(" JPA/EJB3杀死了DA O").如您所见,没有单一的解决方案可以解决该问题,但是我鼓励您阅读其他一些意见并应用您认为最适合您需要的解决方案.
By this approach you get separation of concerns mentioned in the post. From the other hand such an approach (business layer vs data access layer) got a little dose of criticism from Adam Bien's on his blog ("JPA/EJB3 killed the DAO"). As you can see there is no a single solution for the problem, but I encourage to read some other opinions and apply the solution you find the most suitable for your needs.
这篇关于我们应该在哪里使用@Transactional,在哪里使用Service层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!