如何在Windows服务中回滚?

How to roll back in windows Service?

提问人:Mussaib Siddiqui 提问时间:11/10/2016 最后编辑:FabioMussaib Siddiqui 更新时间:11/10/2016 访问量:209

问:

我有一个 Windows 服务,当启动时会转到我定义的路径并收集文件列表,每个文件都有我插入数据库 (Oracle) 中的记录。我的问题是,如果这个数据库出现故障,或者如果有一些异常,我将如何回滚从文件中插入的上一条记录。 例如

我有 10 个文件,每个文件有 5 条记录 解析第 7 个文件时,第 4 条记录上存在某种异常,例如(db down 或其他任何内容)我想回滚从第 7 个文件插入的前 3 条记录,这可能吗?

我的代码在这里..

protected override void OnStart(string[] args)
{
    timer1 = new Timer();
    this.timer1.Interval = 30000;
    this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_tick);
    timer1.Enabled = true;

    Upload.WriteErrorMessage("Service Started");

}

private void timer_tick(object sender,ElapsedEventArgs e)
{
    timer1.Enabled = false;
    SwiftParser.Parse();
    timer1.Enabled = true;
}

protected override void OnStop()
{
    timer1.Enabled = false;
    Upload.WriteErrorMessage("service stoped");
}

我上传数据的方法:

Upload obj = new Upload();
var files = db.SWIFT_FILES.Select(x => x.LASTFILENUMBER).Max();
int sFile = Convert.ToInt32(files);
int sf1 = sFile;
while (true)
{
    string flName = @"D:\Projects\Recon\Nostro\swift\" + sFile.ToString("00000000").Trim() + ".swf";
    if (System.IO.File.Exists(flName))
    {
        obj.SwiftParse(flName);
    }
    else
    {
        break;
    }
    sFile++;
}

在快速解析中,我只是解析文件并从中收集数据并保存在数据库中,这实际上是一个很长的方法,所以我不想在这里弄得一团糟

总之 我制作了一个表格的对象并保存在其中

for(int i=0; i<length of record; i ++)
{
    SwiftTable sw = new SwiftTable();
    sw.acc_no = from file i get acc no;
    sw.amount= ......................;
    sw.bank=.........................;
    db.Add.SwiftTable(sw);
    db.SaveChanges();
}

请告诉我有什么解决方法,或者任何建议都将得到充分的帮助。 我正在使用 Oracle 数据库和 c# windows 服务和实体框架 5

C# Oracle 实体框架 Windows-Services

评论


答:

1赞 JanneP 11/10/2016 #1

最简单的方法是将调用置于文件循环之外。另一种方法是使用事务,如下所示:db.SaveChanges()

((IObjectContextAdapter)db).ObjectContext.Connection.Open();

using (System.Data.Common.DbTransaction transaction = ((IObjectContextAdapter)db).ObjectContext.Connection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
    {
        try
        {
            using (db)
            {
                for(int i=0; i<length of record; i ++)
                {
                    SwiftTable sw = new SwiftTable();
                    sw.acc_no = from file i get acc no;
                    sw.amount= ......................;
                    sw.bank=.........................;
                    db.Add.SwiftTable(sw);
                    db.SaveChanges();
                }

                transaction.Commit();
            }
        }
        catch (Exception ex)
        {
            transaction.Rollback();
        }
    }

评论

0赞 Mussaib Siddiqui 11/10/2016
我收到 InvalidoperationException,说连接未打开。.有什么想法吗?您的解决方案看起来不错@JanneP
0赞 JanneP 11/10/2016
对不起,我编辑了我的答案以包括连接打开。
0赞 Mussaib Siddiqui 11/10/2016
另一个例外是 Dbcontext 已被释放
0赞 JanneP 11/10/2016
如果您有未释放的上下文,它应该可以工作。通过在打开连接之前创建上下文来测试它,并删除代码的 using 部分。这样一来,你就可以始终保持上下文的活力。只要确保你以后摆脱它。
0赞 Mussaib Siddiqui 11/10/2016
谢谢男人..嘿,如果我不删除使用怎么办?它在不删除使用的情况下工作正常,我应该在哪里处理我的上下文?