如果前两个操作成功完成但第三个事务无法完成,我该如何回滚操作

时间:2014-06-05 06:47:54

标签: c# stored-procedures gmail

我正在开发.net应用程序,其中一次执行三个操作。首先,将记录插入表中(我调用存储过程将记录插入表中),然后第一封邮件发送给管理员,第二封邮件发送给填写表单的用户..我不确定至于如何成功地执行这三个操作。如果前两个操作完成且上一个操作无法完成,则必须回滚。我正在考虑使用事务来执行此操作,并在任何操作未完成时使用try catch异常回滚。但我怀疑的是,如果插入记录并发送第一封邮件并在第二封邮件发送时发送邮件失败,则是第一封邮件发送回滚!!!还有另一种方法吗?

1 个答案:

答案 0 :(得分:0)

首先,如果您可以将不同类型的逻辑分离为更模块化的方法,那么它总是更好的分离。数据库操作不应该依赖于电子邮件发送操作,不同模块用于不同目的,还要考虑依赖注入以便于测试。

无论如何,如果我正确地理解了你的问题,我相信你想要这样的东西吗?:

public delegate void CustomEventHandler(object sender, CustomEventArgs e);

public class CustomEventArgs : EventArgs
{
    public enum EventTypes
    {
        Success,
        Error
    }

    public CustomEventArgs(string s, EventTypes type)
    {
        msg = s;
        this.type = type;
    }
    private readonly string msg;

    public string Message
    {
        get { return msg; }
    }

    private readonly EventTypes type;

    public EventTypes Type
    {
        get { return type; }
    }
}

public class TransactionManager
{
    public event CustomEventHandler CustomEvent;

    public void PerformTransaction()
    {
        try
        {
            using (var scope = new TransactionScope())
            {
                //Perform your workload

                scope.Complete();

            }

            if (CustomEvent != null)
                CustomEvent(this,
                    new CustomEventArgs("Transaction performed successfully message",
                        CustomEventArgs.EventTypes.Success));
        }
        catch (Exception exception)
        {
            if (CustomEvent != null)
                CustomEvent(this,
                    new CustomEventArgs(exception.Message, CustomEventArgs.EventTypes.Error));                
        }
    }

}

public class Engine
{

    public void PerformWorkload()
    {
        var tm = new TransactionManager();

        tm.CustomEvent += transaction_CustomEvent;

        tm.PerformTransaction();

    }

    private void transaction_CustomEvent(object sender, CustomEventArgs e)
    {
        //Simulate send operation successful mail
        switch (e.Type)
        {
            case CustomEventArgs.EventTypes.Error:
                //Send error mail
                break;
            case CustomEventArgs.EventTypes.Success:
                //Send success email
                break;
        }
    }
}