多个系统使用相同的父标识密钥作为外键值

时间:2019-07-17 15:23:45

标签: sql-server foreign-keys identity

我将SQL Server中的Identity用作父表(Part)的主键和从属表(TestResult)的外键。依赖于TestResult的表还将Identity用作其主键(TR_ID,PartID)的元素。在一个事务中,一个部分与许多TestResults一起插入。

如果生成错误,则事务将回滚。

问题:在这种多用户环境中,如果两台不同的计算机试图以完全相同的毫秒数(在Part表中有一个timestamp字段而不是键的一部分)写入这样的事务,则从两台计算机插入的所有TestResult记录最终都指向单个Part记录。如何保证每台计算机上的部件表都获得唯一的身份密钥值?

我将TestResult表的主键更改为使用自然键(TestID)代替代理TR_ID。

SqlTransaction partResultTransaction = null;

try
{
    string insertPRString = "INSERT PartResult (Datestamp, Workcenter, PartNo, GaugeID, Shift, Lathe, Result, Spare1, Spare2, Spare3, Spare4, Spare5) " +
                            "VALUES (@Datestamp, @Workcenter, @PartNo, @GaugeID, @Shift, @Lathe, @Result, @Spare1, @Spare2, @Spare3, @Spare4, @Spare5);" +
                            "SELECT IDENT_CURRENT('PartResult')";

    SqlCommand insertCommand = new SqlCommand(insertPRString, oConnection);
    insertCommand.Parameters.AddWithValue("@Datestamp", datestamp);
    .....

    Decimal d = (Decimal)insertCommand.ExecuteScalar();
    long lPartResultKey = (long)d;

    string insertTRString = "INSERT TestResult (intPartResultID, TestID, LongDescription, ShortDescription, TestValue, LowLimit, HighLimit) " +
                            "VALUES (@intPartResultID, @TestID, @LongDescription, @ShortDescription, @TestValue, @LowLimit, @HighLimit)";

    foreach (RDTestResult tr in rdpi.RDTestResults)
    {
        insertCommand = new SqlCommand(insertTRString, oConnection);
        insertCommand.Transaction = partResultTransaction;

        if (tr.Status != TestStatus.Disabled && tr.Runstate == RunState.Completed)
        {
            insertCommand.Parameters.AddWithValue("@intPartResultID", lPartResultKey);
            insertCommand.Parameters.AddWithValue("@TestID", tr.ID);
            insertCommand.Parameters.AddWithValue("@LongDescription", tr.Description);
            insertCommand.Parameters.AddWithValue("@ShortDescription", tr.Abbreviation);
            insertCommand.Parameters.AddWithValue("@TestValue", tr.Solution);
            insertCommand.Parameters.AddWithValue("@LowLimit", tr.LowLimit);
            insertCommand.Parameters.AddWithValue("@HighLimit", tr.HighLimit);

            insertCommand.ExecuteNonQuery();
        }
    }

    if (partResultTransaction != null)
        partResultTransaction.Commit();
}
catch (Exception ex)
{
    try
    {
        AppendSQLServer1LogFile("Transaction Commit failed attempting to write a new part result, rolling back....");

        if (partResultTransaction != null)
            partResultTransaction.Rollback();
    }
    catch (Exception ex2)
    {
        AppendSQLServer1LogFile("Transaction Rollback failed attempting to write a new part result.");
    }

    BufferData(rdpi);
}
finally
{
    oConnection.Close();
}

来自两台计算机的从属TestResult记录位于共享数据库中Part记录下。

0 个答案:

没有答案