简体   繁体   English

sql 服务器的服务冗余

[英]Service redundancy with sql server

I have 2 instance of the same service running on different machines.我有 2 个相同服务的实例在不同的机器上运行。 This is to ensure high availability (if one machine falls, killing the first service, then the second is still available).这是为了确保高可用性(如果一台机器宕机,杀死第一个服务,那么第二个仍然可用)。

These two service update & delete the same rows in SQL Server table at the same time when a bus event is triggered.这两个服务在触发总线事件时同时更新和删除 SQL 服务器表中的相同行。 So, I usually get a LinqToSql ChangeConflictException on bus event raise.因此,我通常会在总线事件引发时收到 LinqToSql ChangeConflictException

To handle this, I currently surround the SubmitChanges with try catch and do nothing in case of ChangeConflictException .为了处理这个问题,我目前用try catch包围SubmitChanges并且在ChangeConflictException的情况下什么也不做。

Is there any cleaner way?有没有更清洁的方法?

Is it possible to lock the whole table using Linq to SQL?是否可以使用 Linq 到 SQL 锁定整个表? (so that one of the service will wait for the lock to be released before trying to do the update). (以便其中一项服务在尝试更新之前等待锁被释放)。

My approach for this kind of locking would be to use a distributed lock, rather than locking the target table itself.我对这种锁定的方法是使用分布式锁,而不是锁定目标表本身。 If anything, it would allow you to include more logic within the process.如果有的话,它将允许您在流程中包含更多逻辑。 You can't use the standard c# lock method because you've got multiple instances of the same application that would need to share the same lock, so you'd have to use something centralised.您不能使用标准的 c# 锁定方法,因为您有同一个应用程序的多个实例需要共享同一个锁,因此您必须使用集中的东西。

I've used SQL Server's sp_getapplock for this before - you just need a single SQL database that is accessible by each instance of the application.我之前使用过 SQL 服务器的sp_getapplock - 您只需要一个 SQL 数据库,应用程序的每个实例都可以访问该数据库。 You can either call this SP manually, or I know there are a few nuget packages that wrap this process up to make it a bit easier to integrate with.你可以手动调用这个 SP,或者我知道有一些 nuget 包可以将这个过程包装起来,使它更容易集成。 But you've also got the option of doing the same kind of thing with distributed locks in Redis , and probably most other cache solutions, if you've got any of those involved in your solution.但是您也可以选择在 Redis 和大多数其他缓存解决方案中使用分布式锁做同样的事情,如果您的解决方案中涉及任何这些。

Essentially you can just take a new lock around whatever action you want to protect from being run concurrently.本质上,您可以对要防止同时运行的任何操作进行新的锁定。 In your case, it would avoid multiple updates to that table running at the same time.在您的情况下,它将避免同时运行对该表的多个更新。

That being said, you could also consider looking at how these events are raised and handled, and seeing if you could get the resiliency you're looking for at that level instead.话虽如此,您还可以考虑查看这些事件是如何引发和处理的,并看看您是否可以在该级别获得您正在寻找的弹性。 Just off the top of my head, something like RabbitMQ (and other message queues) allows for a lot of the failure situations to be handled at the message delivery level.就在我的脑海中,像RabbitMQ (和其他消息队列)这样的东西允许在消息传递级别处理许多故障情况。 I don't know if that would be worth looking into as well (if anything, it might avoid these events from being processed multiple times if they only need to be processed once), but it might be helpful to check that.我不知道这是否也值得研究(如果有的话,如果它们只需要处理一次,它可能会避免这些事件被多次处理),但检查一下可能会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM