2012-02-08 41 views
1

我在后台任务方法(由Quartz运行)中使用UnitOfWork,并在Guiddle-persist之上进行休眠。后台任务调用一个服务,该服务需要在当前事务的任务中提交 - 并继续进行另一个事务。我如何提交当前的UnitOfWork并创建一个新的?如何提交当前的guice-persist UnitOfWork?

class BackgroundJob { 
    @Inject UnitOfWork unitOfWork; 
    @Inject MyService myService; 
    public void run() { 
     try { 
      unitOfWork.begin(); 
      myService.foo(); 
     } finally { 
      unitOfWork.end(); 
} } } 

class MyServiceImpl implements MyService { 
    @Override public void foo() { 
     foo1(); 
     // I would like to commit here and start a new transaction 
     foo2(); 
} } 

的服务也可以由吉斯管理,但它是一个单例,并没有访问调用UnitOfWork的是

理想情况下,我不想更改服务签名。一个解决方法是给调用者提供两个UnitOfWork作为foo()的参数,但这似乎有点黑客入侵。

编辑:为了便于使用未来的同胞读者,这里是我的执行由ColinD给出的解决方案,这正好满足要求的:

class BackgroundJob { 
    @Inject UnitOfWork unitOfWork; 
    @Inject MyService myService; 
    public void run() { 
     try { 
      unitOfWork.begin(); 
      myService.foo(); 
     } finally { 
      unitOfWork.end(); 
} } } 

class MyServiceImpl implements MyService { 
    @Override public void foo() { 
     foo1(); 
     foo2(); 
    } 
    @Transactional private void foo1() { ... } 
    @Transactional private void foo2() { ... } 
} 
+0

只是一个观察,你不想在异常情况下回滚事务吗? – 2012-02-08 18:05:55

+0

那么,如果第一个事务有异常,我想回滚第一个,但是一旦提交,我不在乎。如果第二个失败,我想回滚第二个事务,但不是第一个。因此我需要有*两个*交易。 – 2012-02-08 19:43:41

回答

4

如果我没有记错,工作在吉斯单位坚持是一个事务。相反,它代表一个工作单元,例如单个Web请求,或者在您的情况下是单个后台工作。我认为单个数据库连接用于整个工作单元,但该工作单元可能有多个不同的事务。事实上,我认为只是开始和结束一个工作单位不会导致任何交易的开始或结束。

我想你想要做的是用@Transactional注释foo1()foo2()(但不是foo())。只要没有外部事务包装这两个调用,它们将分别在单独的事务中运行。

0

这可能适合该法案。

class BackgroundJob { 
    @Inject UnitOfWork unitOfWork; 
    @Inject MyService myService; 

    public void run() { 
     try { 
      unitOfWork.begin(); 
      myService.foo1(); 
      unitOfWork.end(); 
      unitOfWork.begin(); 
      myService.foo2(); 
      unitOfWork.end(); 
     } finally { 
      unitOfWork.end(); 
     } 
    } 
} 
相关问题