我正在开发一个应用程序,该应用程序在收到PayPal即时付款通知时应创建产品(如运输保险单)。不幸的是,PayPal有时会发送重复通知。此外,还有另一个第三方在从PayPal获得更新时同时执行Web服务更新。IsolationLevel.RepeatableRead以防止重复
下面是涉及的数据库表的基本图。
// table "package"
// columns packageID, policyID, other data...
//
// table "insurancepolicy"
// columns policyID, coverageAmount, other data...
这里是什么,我想要做一个基本图:
using (SqlConnection conn = new SqlConnection(...))
{
sqlTransaction sqlTrans = conn.BeginTransaction(IsolationLevel.RepeatableRead);
// Calls a stored procedure that checks if the foreign key in the transaction table has a value.
if (PackageDB.HasInsurancePolicy(packageID, conn))
{
sqlTrans.Commit();
return false;
}
// Insert row in foreign table.
int policyID = InsurancePolicyDB.Insert(coverageAmount, conn);
if (policyID <= 0)
{
sqlTrans.Rollback();
return false;
}
// Assign foreign key to parent table. If this fails, roll back everything.
bool assigned = PackageDB.AssignPolicyID(packageID, policyID, conn);
if (!assigned)
{
sqlTrans.Rollback();
return false;
}
}
如果有两个(或更多)的线程(或进程或应用程序)在同一时间做这个,我想第一个线程在没有policyID的情况下锁定“包”行,直到创建策略并将策略ID分配给包表。然后,在policyID分配给包表后,锁将被释放。我希望调用这个相同代码的另一个线程在读取包行时暂停,以确保它没有第一个policyID。当第一个事务的锁被释放时,我希望第二个事务会看到policyID在那里,因此返回时不插入任何行到策略表中。
注意:由于CRUD数据库设计的,每一个存储过程的参与设置读取(选择),创建(插入),或更新。
这是正确使用RepeatableRead事务隔离吗?
谢谢。
什么是包装:政策关系?它是1:1吗? – Constantin 2008-09-23 23:43:37
它是n:1。父表实际上不是“包”,我只是为了说明而称他们为“包”。实际上,这些“包裹”就像是可以组合并一起运输的订单,整个包裹只有一份保险单。 – devlord 2008-09-24 01:14:06