事务隔离级别是否会解决多线程webapp中的竞争条件?

时间:2014-01-16 13:23:25

标签: sql postgresql nhibernate

我有点困惑该做什么,我有一个Web应用程序以多线程方式处理传入请求(因此几乎可以肯定某些请求是同时处理的)。 现在有一个请求可以创建/更新一天的计​​划。

以下是请求处理的步骤(伪代码,webapp是用NHibernate编写的,但我认为这不重要。)

begin transaction

day_id = select id from day where day.date = request.date
if not day_id:
    day.date = request.date
    insert into day ...
    day_id = last insert id
plan.day_id = day_id
insert into plan ...

commit

当同时处理两个请求时,存在明显的竞争条件:

+------+------------------------------+-----------------------------------+
| Step |           Request1           |             Request2              |
+------+------------------------------+-----------------------------------+
| 1    | begin transaction            |                                   |
| 2    | select Day.id where date=:d  | begin transaction                 |
| 3    | not found, insert            | select Day.id where date=:d       |
| 4    | plan.day_id = last_insert_id | not found, insert                 |
| 5.   | insert plan                  | plan.day_id = last_insert_id      |
| 6.   | commit                       | insert plan                       |
| 7.   | commit OK                    | commit                            |
| 8.   |                              | commit NOT OK, duplicate Day.date |
+------+------------------------------+-----------------------------------+

我已经尝试将事务隔离级别设置为可序列化,但它似乎无法解决问题(我甚至不确定它应该解决...)

1 个答案:

答案 0 :(得分:0)

您的比赛条件不是由首先存储的请求引起的。这是由两个同时出现的请求引起的。

如果您的请求是在您身边创建的,那么您需要一种更好的方法来为您的线程选择作业。如果请求不是由您创建的,那么只是很好地处理异常。

交易失败,数据库中的数据没有坏,那么问题是什么?