当前位置: 首页 > 编程语言 > C#

使用负载均衡时如何锁定对象分享

时间:2023-04-10 16:00:51 C#

使用负载均衡时如何锁定对象背景:我正在写一个函数,使用C#对长时间运行的操作进行排队,每3步:1.数据库操作(update/delete/adddata)2.使用webservice做longcalculation3.数据库操作(保存step2的计算结果)在step1的同一个db表上,检查db表的Consistency,比如step1中的items是同样(参见下面更详细的示例)为了避免脏数据或损坏,我使用锁对象(静态单例对象)来确保整个事务完成3个步骤。因为当多个用户在调用该函数执行操作时,他们可以在自己操作的不同步骤修改同一个db表而无需这个锁,例如user2在他的step1中删除了itemA,user1正在检查A是否仍然存在在他的第3步。(附加信息:我还使用实体框架中的TransactionScope来确保每个数据库操作都是事务,但可重复和可读。)但是,我需要将它放在使用负载均衡机制,所以其实我的锁对象是不会生效的,因为函数会部署在不同的服务器上。问题:如何让我的锁对象在上述情况下工作?这是一个棘手的问题——您需要分布式锁或某种共享状态。由于您已经拥有数据库,您可以将您的实现从“静态C#锁”更改为在整个“交易”过程中为您管理锁。你没有说你使用的是什么数据库,但如果它是SQLServer,那么你可以使用应用程序锁来实现这一点。这允许您明确地“锁定”该对象,所有其他客户端将等待该对象被解锁。查看:http://technet.microsoft.com/en-us/library/ms189823.aspx我在下面写了一个示例实现。启动两个实例进行测试。以上就是C#学习教程:使用负载均衡时如何锁定对象共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注——usingSystem;使用系统数据;使用系统.Data.SqlClient;使用System.Transactions;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){varlocker=newSqlApplicationLock("MyAceApplication","Server=xxx;Database=scratch;UserId=xx;Password=xxx;");Console.WriteLine("获取锁");using(locker.TakeLock(TimeSpan.FromMinutes(2))){Console.WriteLine("LockAquired,doingworkwhilenoonecando.Pressanykeytoreleasethelock.");控制台.ReadKey();}Console.WriteLine("锁定解除");}classSqlApplicationLock:IDisposable{privatereadonlyString_uniqueId;私有只读SqlConnection_sqlConnection;私人布尔值_isLockTaken=false;publicSqlApplicationLock(StringuniqueId,StringconnectionString){_uniqueId=uniqueId;_sqlConnection=newSqlConnection(connectionString);_sqlConnection.Open();}公共IDisposableTakeLock(TimeSpantakeLockTimeout){使用(TransactionScopetransactionScope=newTransactionScope(TransactionScopeOption.Suppress)){SqlCommandsqlCommand=newSqlCommand("sp_getapplock",_sqlConnection);sqlCommand.CommandType=CommandType.StoredProcedure;sqlCommand.Commandint)takeLock=(.TotalSeconds;sqlCommand.Parameters.AddWithValue("Resource",_uniqueId);sqlCommand.Parameters.AddWithValue("LockOwner","Session");sqlCommand.Parameters.AddWithValue("LockMode","独占");sqlCommand.Parameters.AddWithValue("LockTimeout",(Int32)takeLockTimeout.TotalMilliseconds);SqlParameterreturnValue=sqlCommand.Parameters.Add("ReturnValue",SqlDbType.Int);returnValue.Direction=ParameterDirection.ReturnValue;sqlCommand.ExecuteNonQuery();if((int)returnValue.Value本文采集自网络,不代表立场,如涉及侵权,请点击维权联系管理员删除,转载请注明来源: