Lock on an class member vs having that object initialized in class' method?
因此,我有此服务,我们将其称为" MyService "。 MyService有一个公共方法,即" executeBatchJob ",顾名思义,它将执行一个batchJob,简而言之,从数据库中检索一些数据,在某个时候,我有一个非常类似于实体的对象,带有ID和记录列表。在我的方法executeBatchJob中,进行了一些检查,当满足某些条件时,将实体写入某个位置并重新初始化(新ID,不同的记录),但是请注意,它发生在executeBatchJob调用的私有方法中。在其他条件下,采用不同的私有方法,记录将添加到该实体保存的记录列表中。
我的问题是:由于服务可能由多个过程调用:将实体声明为类成员(私有只读)并在需要时将其锁定,然后使用一种可以清理实体的方法更好吗?下一步的状态。还是最好在我的方法executeBatchJob中声明并使用此对象,但是通过所有私有方法拖动该对象,因为该对象的状态可能会在多个"级别"变化?
为了向您说明我在解释什么:
这是myEntity:
1 2 3 4 5 6 7 8 9 10 11 | public class MyEntity { public int Id { get; set; } public List<Record> Records { get; set; } public void CleanUp(int newId) { Id = newId; Records.Clear(); } } |
这是带锁的myService:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class MyService : IMyService { private readonly MyEntity _myEntity; public MyService() { _myEntity = new MyEntity(); } public void executeBatchJob(int batchId) { //some code lock(_myEntity) { // More code and call to some private method _myEntity.CleanUp(); } // still more code } } |
或使用第二个选项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class MyService : IMyService { public MyService() { } public void executeBatchJob(int batchId) { MyEntity myEntity = new MyEntity(); APrivateMethodInExecuteBatchJob(myEntity); // more code } private returnResult APrivateMethodInExecuteBatchJob(MyEntity myEntity) { // Some manipulation of myEntity // some code, with another call to a private method with myEntity, and manipulation of myEntity // ... write the entity myRepository.write(myEntity); } } |
据我所知,要提供更多上下文,每次将写入实体时,都必须对其进行清理,在第二种选择中,我可以做一个" new MyEntity()"(这使得从业务angular来看更有意义)。
对我来说,第二种解决方案是更合理,更合理的方法,但是,我将有几个私有方法来移动对象,有时只是将其传递给另一个私有方法而无需"传递"之外的任何其他操作。转到其他私有方法...根本不干净...
这就是为什么我需要您的建议/意见。
如果不应该保留实体的状态,那么我认为在选项2中拥有幂等方法要好得多。如果可以使这些方法静态化,那么您将得到一个简单得多的体系结构。
您已经确定需要将资源锁定在选项1中,并且只要在清理过程中丢弃该状态就不会出现令人头疼的问题。
我唯一能看到类似选项1的原因是该实体是由使用之间没有清除的交易建立的,还是该实体由于某种原因创建起来非常昂贵。
使用
1 | public class MyEntity: IDisposable; |
然后,您可以将第二个选项与using关键字一起使用。
您可以在此处查看有关实施方式和方法的示例。 https://docs.microsoft.com/zh-cn/dotnet/standard/garbage-collection/implementing-dispose
示例代码:
1 2 3 4 5 6 7 8 9 10 | public void executeBatchJob(int batchId) { using (vMyEntity myEntity = new MyEntity();) { APrivateMethodInExecuteBatchJob(myEntity); // more code } } |
通常,尽量避免在不需要时使用锁。它可能会创建竞争条件,这将使您的应用程序响应速度变慢。