我有点困惑该做什么,我有一个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 |
+------+------------------------------+-----------------------------------+
我已经尝试将事务隔离级别设置为可序列化,但它似乎无法解决问题(我甚至不确定它应该解决...)
答案 0 :(得分:0)
您的比赛条件不是由首先存储的请求引起的。这是由两个同时出现的请求引起的。
如果您的请求是在您身边创建的,那么您需要一种更好的方法来为您的线程选择作业。如果请求不是由您创建的,那么只是很好地处理异常。
交易失败,数据库中的数据没有坏,那么问题是什么?