NHibernate(c#) 中的并发冲突示例

发布于 2024-08-24 05:10:32 字数 288 浏览 3 评论 0原文

很长一段时间以来,我一直在阅读 NHibernate 中的乐观并发。如果我的理解是正确的,那么下面的示例应该很好。

考虑两个事务 T1 和 T2。

  1. 当 T1 和 T2 同时完成时,状态(数据库条目)将使用最新更新(T1 或 T2)的值进行更新。

尽管它在概念上似乎是合理的,但为了理解和集成测试的目的,我如何模拟它?

有人可以帮我编写一个示例 c# 代码吗?

谢谢,

维杰

For quite some time , I was reading about the optimistic concurrency in NHibernate. If what i understood was correct then the below sample should hold good.

Consider two transactions T1 and T2.

  1. When T1 and T2 are done simultaneously , the state(DB entries) gets updated with the values of the most latest update.(T1 or T2).

Though it seems to be conceptually sound , how do i simulate this for the purpose of understanding and integration testing.?

Can someone help me with a sample c# code.?

Thanks ,

vijay

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很糊涂小朋友 2024-08-31 05:10:32

概念上:

  1. 使用2个线程来执行T1和2;并且用于同步访问的共享锁
  2. 线程 1 获取锁并执行 T1
  3. 线程 2 获取相同的锁并执行 T2
  4. 其中一个事务将失败并出现乐观并发异常

Conceptually :

  1. use 2 threads for performing T1 and 2; and a shared lock to synchronize access
  2. thread1 acquires lock and performs T1
  3. thread2 acquires the same lock and performs T2
  4. one of the transactions will fail with Optimistic Concurrency Exception
鲸落 2024-08-31 05:10:32

现在,经过大量谷歌搜索,我找到了一种相当简单的方法。以下是重现此操作的步骤。

  1. 在 Get() 和 Update() 方法之间有一个 Thread.Sleep(),仅适用于一个用户(进程 1)。

  2. 当进程1运行时,启动没有遇到Thread.Sleep()的进程2,并在进程1之前完成更新。

    当进程

  3. 现在进程2已经修改了数据库中的数据,现在当进程1尝试更新数据时,NHibernate会抛出一个陈旧对象异常。

请参考以下代码片段。

public void Update(int empid)
    {
        Employee person = this.dalService.GetByEntityId(empid);
        person.Name = "Process 1";

        // At this point , Update the Person table  manually using raw sql query
        // such as this 'Update Person Set Name = 'Process 2'where empid = @empid;


        // When the update is performed , it is expected to throw the exception , as the in memory data
        // is different from the one in database.
        if (username.equals("Bob"))
        {
            Thread.Sleep(50000);
            // If this is a website, have the above condition, so that it is simulated only for one user.
        }

        this.dalService.Update(person);
    }

Now after a lot of googling , i have found out a fairly simple way to do that .The following are the steps to reproduce this.

  1. Have a Thread.Sleep() between the Get() and Update() methods, for only one user(process 1 ).

  2. When process 1 is running , start process 2 which doesnt encounter the Thread.Sleep() and completes the update before the process 1 does .

  3. Now process 2 has modified the data in the data base, now when process 1 tries to update the data, NHibernate throws a stale object exception.

Please refer the following code snippet.

public void Update(int empid)
    {
        Employee person = this.dalService.GetByEntityId(empid);
        person.Name = "Process 1";

        // At this point , Update the Person table  manually using raw sql query
        // such as this 'Update Person Set Name = 'Process 2'where empid = @empid;


        // When the update is performed , it is expected to throw the exception , as the in memory data
        // is different from the one in database.
        if (username.equals("Bob"))
        {
            Thread.Sleep(50000);
            // If this is a website, have the above condition, so that it is simulated only for one user.
        }

        this.dalService.Update(person);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文