2010-12-16 161 views
10

考虑一下我有一个控制器方法get(),它调用几个使用数据库的服务方法。交易:控制器vs服务

使整个控制器方法是事务性的还是只是每个服务方法都是正确的?

在我看来,我们必须让get()事务,因为它执行相关的操作。

谢谢!

回答

5

我更喜欢只制作事务性的服务方法,这些方法需要是事务性的,并且控制不在控制器中的服务中的事务性。您可以创建一个服务方法,该方法使用其他服务方法,并使用spring事务在@Transactional注释中使用传播来管理事务。

@Transactional(propagation =...) 

编辑

如果我有2种方法,例如saveUser()和saveEmail()(因为我存储在数据库中的电子邮件,发送它们 - 就像一个队列)我想创建我的服务方法saveUserAndSendEmail(用户用户),这将是事务性的。这个方法会调用saveUser和saveEmail()中的每一个在@Repository组件中,因为它们处理数据库。因此,我会将它们放入@Repository组件中用于处理数据库的方法,然后控制@Service组件中的事务性。然后,控制器只需要担心在需要时提供数据和呼叫。但是我做了一个事务,因为我不想在数据库中提交更改,直到整个方法成功执行。

但这是我通常使用的风格,我并不是说这一定是要走的路。

+0

它似乎是首选设计,但为什么?考虑我需要loadMenuItems(),loadUserInfo(),loadDocument() - 很多方法。根据你我必须创建一个loadMenuItemsAndUserInfoAndDocument()方法 - 可以吗? – 2010-12-16 16:23:35

+0

@Andrey我没有说过这是首选设计。这是我平常工作的方式,因为我更喜欢控制器不需要知道事务管理。根据你的方法的名称开始加载...如果他们只从数据库中真实的,你为什么需要进行交易? – Javi 2010-12-16 16:28:43

+1

那么,如果你有两种方法:createUser(),sendEmail()来自不同的服务(用户和邮件)。而且你需要在一个transactionalal控制器中调用它们。你该怎么办? – 2010-12-16 16:29:56

7

这完全取决于您,以及您如何解读自己的业务逻辑。

Spring并不关心你把事务边界放在哪里,当然也不会限制你把它们放在你的DAO类上。

所以是的,将@Transactional添加到您的控制器方法是完全有效的。

+6

恕我直言,@Transactional在控制器从体系结构角度(MVC)没有太多的意义。我的意思是,控制器不应该意识到持久层,并且您可能必须在您的控制器层不再存在的桌面应用程序中重用您的业务逻辑......我认为事务性应该在@Service层中定义。 – 2010-12-16 23:35:55