2

我有一些代码可以从表格中读取要发送的邮件列表并发送它们。

按顺序进行的操作是:

  1. 将标志设置为在表中发送
  2. 拨打自动电话
  3. 犯罪

在自动调用之前进行更新的原因是,如果出现故障,我可以回滚而不进行自动调用。但如果反过来,我最终可能会在无法更新记录的情况下拨打电话(如果数据库出现问题)。

public class MyDao {

    public void doSomethingOnDb() {
        try {
            // operation 1 : execute an update (setting the letter as sent)
            // operation 2 : make automatic call    
            // operation 3 : commit
        }
        catch(Exception e) {
            // Rollback
        }
    }   
}

我在这里不喜欢的是,我正在放置一个在 dao 中进行自动调用的功能,而这不是 dao 应该做的。但是,如果我将逻辑分开,我无法确定表中的标志是真实的。我们可以拨打电话,但无法将标志更新到数据库中:

public class MyDao {

    public void doSomethingOnDb() {
        try {
            // operation 1 : execute an update (setting the letter as sent)
            // operation 2 : commit
        }
        catch(Exception e) {
            // Rollback
        }

    }   
}

public void someOtherMethodSomewhere() {
    try { 
        new MyDao().doSomethingOnDb();
        // operation 3 : make the automatic call
    }
    catch(Exception e) {
    }
}

那么,你会怎么做呢?还有其他解决方案吗?

4

2 回答 2

0

这是一个经典的多资源事务(分布式事务)。我可以建议您阅读有关 XA 事务的内容,例如两阶段提交协议

也许您正在尝试解决另一个问题?如果我理解正确,那么也许您只需要更改代码?例如,您可以从 dao 返回成功:

if(doSomethingOnDb()) 
{
   //make the automatic call
}

即,如果更改成功完成并提交,则 dao 调用返回 true。

如果失败,您也可以从 doSomethingOnDb 抛出异常,在这种情况下

try { 
    new MyDao().doSomethingOnDb();
    // operation 3 : make the automatic call
}
catch(Exception e) {
}

跳过operation 3并落入 catch 块。

或者只是将一个函数传递给 dao 来执行:

public void doSomethingOnDb(Runnable precommit) {
    try {
        // operation 1 : execute an update (setting the letter as sent)
        precommit.run();    
        // operation 3 : commit
    }
    catch(Exception e) {
        // Rollback
    }
}   

...
myDao.doSomethingOnDb(new Runnable()
{
   void run()
   {
        // operation 3 : make the automatic call
   }
});
于 2013-09-05T14:25:46.530 回答
0

你不能简单地将DAO操作分成子方法吗?就像是:

public class MyDao {
    public void executeAnUpdate() {...}
    public void commit() {...}
}

public class MyBusiness {
    public void run() {
        myDao.executeAnUpdate();
        // make the automatic call
        myDao.commit();
    }
}
于 2013-09-05T14:34:18.727 回答