同时操作多个数据库

liuwei19860906 2018-10-30 10:56:30
加精
局域网系统中,某个系统做操作需要对多个数据库进行数据插入及修改。
现在想要实现一方面操作失败了整体做回滚。
可是Transaction 是针对单个conn的,在执行多个commit的时候出错会造成不同步的可能。
这个方法如何解决。
以前是要坐断点续传的,但是并不切合实际流程。
...全文
2095 64 打赏 收藏 转发到动态 举报
写回复
用AI写文章
64 条回复
切换为时间正序
请发表友善的回复…
发表回复
realmagicSEO 2018-11-17
  • 打赏
  • 举报
回复
没有接触过,学习
qq_556621888 2018-11-15
  • 打赏
  • 举报
回复
真是太厉害了
tq1086 2018-11-09
  • 打赏
  • 举报
回复
业务层不该做这样的事情。如果是自己开发中间件或基础架构组件,需要自己实现两阶段提交,工程量和复杂程度非常大。
  • 打赏
  • 举报
回复
正因为不管是“第三个确认和回滚阶段”还是分布式的“最终一致性”处理都是一个艺术性的设计任务,所以要针对业务逻辑来设计开发。不可能用一个低级的关系数据库事务 Commit 概念随便往上“一套用”就解决了问题。
  • 打赏
  • 举报
回复
可以说“物极必反”。 在最底层、最低级的部分,我们一定还是依赖于数据库事务机制来把重要的信息持久化。但是在高层,在分布式系统设计中,我们抛弃传统数据库改变,而是使用电信级的面向对象的内存微服务该概念。 不是几十个进程、几千个线程去对同步加锁地改变数据库,不是满脑子只有“数据库表增删改查”。而是设计几百万个独立的缓存对象的消息通讯机制。
  • 打赏
  • 举报
回复
引用 83 楼 tq1086 的回复:
业务层不该做这样的事情。如果是自己开发中间件或基础架构组件,需要自己实现两阶段提交,工程量和复杂程度非常大。
所谓的“两阶段提交”的原型,从一开始就写代码说明了的。而且 lz 的问题中从一开始就知道,lz 反复强调过他发现两阶段提交时遇到了前边的 commit 成功而后边的 commit 失败的情况!实际上前边讨论了数次两阶段提交问题,不是空洞地概念,而是反复实际讨论过了。 两阶段不能保证最总一致性,所以需要三阶段提交。也就是说在两阶段提交之后,仍然需要一个核对校验过程,来给出错的整个事务运行整体的冲销动做。 这不但没有减少复杂性,而且传统的关系数据库事务其实是性能的杀手,在分布式跨跨多个服务器时更是如此。所以现在的追求最终一致性的许多分布式设计是与这种知道最传统的“数据库事务”想法正相反地做法——异步地、根本不用数据库事务的!
  • 打赏
  • 举报
回复
引用 73 楼 wxf54318 的回复:
以前接触过软件a用oracle,软件b用mysql,软件a把实时数据写到文件,软件b读取文件以要求的形式显示数据
重点在于,以什么框架来保证”当内部是异步执行的业务事务出现意外之后,保证数据一致性“?
q467132016123 2018-11-08
  • 打赏
  • 举报
回复
实在厉害,佩服
左玉东 2018-11-08
  • 打赏
  • 举报
回复
TOP3098 2018-11-07
  • 打赏
  • 举报
回复
多开一个线程负责数据同步的方案靠谱一些
sp1234_maJia 2018-11-07
  • 打赏
  • 举报
回复
对于每一种实际的业务,你可以把数据装入上面的 test 框架代码中,并且在运行时动态组成 List<Task> 和 List<Action> 类型的参数。很清晰地成套路地实现并发处理的业务逻辑。
sp1234_maJia 2018-11-07
  • 打赏
  • 举报
回复
对于实际的业务,实际上要将这里的 Action 中的关键内容持久化,以便即使是进程重启、甚至换到其它服务器启动了之后,也能执行
await Task.WhenAll(rollback.......)
部分代码。所以就针对不同类型的业务,设计不同的 Action,调用日志内容来进行回滚。
sp1234_maJia 2018-11-07
  • 打赏
  • 举报
回复
我写一个控制台程序来大致 demo 这个框架的一部分机制:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Task> work = new List<Task>();
            work.Add(Task.Run(() => Console.WriteLine("第一件事儿")));
            work.Add(Task.Run(() => Console.WriteLine("第二件事儿")));
            work.Add(Task.Run(() => Console.WriteLine("第三件事儿")));
            work.Add(Task.Run(async () =>
            {
                await Task.Delay(1000);
                Console.WriteLine("第四件事儿");
                //throw new Exception("失败!");
            }));
            List<Action> rollback = new List<Action>();
            rollback.Add(() => Console.WriteLine("回滚第一件事儿"));
            rollback.Add(() => Console.WriteLine("回滚第二件事儿"));
            rollback.Add(() => Console.WriteLine("回滚第三件事儿"));
            rollback.Add(() => Console.WriteLine("回滚第四件事儿"));
            test(work, rollback);
            Console.WriteLine(".....................按任意键结束");
            Console.ReadKey();
        }

        private static async void test(List<Task> work, List<Action> rollback)
        {
            try
            {
                await Task.WhenAll(work);
            }
            catch (Exception)
            {
                await Task.WhenAll(rollback.Select(proc => Task.Run(proc)));
                throw;
            }
        }
    }
}
这里可以看到,方法 test 它异步并发执行了“第一件事儿,第二件事儿,第三件事儿,第四件事儿”;一旦遇到失败情况,则会异步并发执行是先注册的四个 Action 委托,然后再抛出之前发现的异常。
wxf54318 2018-11-07
  • 打赏
  • 举报
回复
以前接触过软件a用oracle,软件b用mysql,软件a把实时数据写到文件,软件b读取文件以要求的形式显示数据
qq_43629386 2018-11-07
  • 打赏
  • 举报
回复
这个有点6了,多开得配置好吧
qq_37209000 2018-11-07
  • 打赏
  • 举报
回复
看性能需求,如果性能要求不高,生产环境良好,你完全可以 插入数据->查询插入结果->对比结果->对比完成->回滚否?-> ... ->直到完成
adad888 2018-11-07
  • 打赏
  • 举报
回复
这是个统计年鉴的http://nianjian.xiaze.com/tags.php?/%E4%B8%B4%E5%A4%8F%E5%B8%82%E5%B9%B4%E9%89%B4/1/13541576977/
  • 打赏
  • 举报
回复
在我们测试一个程序质量时,最起码地,我们要假设进程中断或者电源被别有用心的用户踢掉为前提,来测试程序数据安全性。此时一些所谓的编程说法自然就站不住脚了。 分布式的协同的困难并不是数据库问题,而是跨进程调用了多种服务。并且通常(为了保证最起码的性能)是异步的。
  • 打赏
  • 举报
回复
使用数据库的 Commit 操作,你可以将多个数据库提交动做放到过程最后,并且仍然是处理 catch 部分的业务数据回滚,同时假设进程崩溃重启、那么你还是需要另外进程重启之后再来一遍校验回滚所有已经 Commit 了的业务数据。所以数据库方式要想做到数据正确一致,也还是要自己编写在 Commit 之后的一趟扫描确认程序。 但是这并不是我要强调的重点。更大的问题是,实际上关系数据库事务加锁是性能的杀手,根本不能用在要求一定性能的高并发分布式系统上。这才是问题的关键!
tqjy14 2018-11-06
  • 打赏
  • 举报
回复
进来看看学学
加载更多回复(44)

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧