MSSQL не возвращает уникальное значение datetime с помощью GetUTCDate () в SP, вызывающем из C # .Net после ожидания не менее 3,3 мс - PullRequest
0 голосов
/ 06 октября 2011

У меня есть следующая хранимая процедура для получения новой даты и времени:

CREATE PROCEDURE [dbo].[GetTransactionTime] 
AS
BEGIN
      SELECT [TransactionTime] = GetUTCDate()
END

Для вызова этого SP я использую простой набор данных C # в локальной БД.

Поскольку datetime из SQL имеет точность 3,3 мс, мне нужно подождать не менее 3,3 мс, чтобы получить новое время. Узнайте больше о точности на MSDN: http://msdn.microsoft.com/en-us/library/ms187819.aspx

В приведенном ниже примере я буду ждать 5 мс:

class Program
{
    static void Main(string[] args)
    {
        var adapter = new SPTableAdapters.TransactionTimeTableAdapter();
        do
        {
            GetTransactionTime(
                    new Func<DateTime>(() => { return (DateTime)adapter.GetTransactionTimeNOW(); })
                );
        } while (true);

    }

    public static DateTime lastTransactionTime = DateTime.MinValue;

    private static bool IsTransactionTimeUnique(DateTime newTransactionTime)
    {
        if (newTransactionTime > lastTransactionTime)
        {
            lastTransactionTime = newTransactionTime;
            return true;
        }
        return false;
    }

    public static void GetTransactionTime(Func<DateTime> funcGetTransactionTime)
    {
        DateTime newTransactionTime = funcGetTransactionTime();
        //MSSQL datetime has a off 3.33ms; try 5ms
        DateTime now = DateTime.UtcNow;
        DateTime max = now.AddMilliseconds(5);

        while (!IsTransactionTimeUnique(newTransactionTime))
        {
            DateTime backup = DateTime.UtcNow;
            if (backup > max) //if we tried more than 5ms.
            {

                //Always try once again.
                newTransactionTime = funcGetTransactionTime();

                if (IsTransactionTimeUnique(newTransactionTime))
                {
                    break;
                }

                Console.WriteLine("FAILED: Old datetime: " + lastTransactionTime.ToBinary() + " New datetime: " + newTransactionTime.ToBinary() + "Start: " + now.Millisecond + " End: " + backup.Millisecond + " Max: " + max.Millisecond);
                return; ;
            }

            newTransactionTime = funcGetTransactionTime();
        }
        Console.WriteLine("OK!");
    }
}

Выход:

FAILED: Old: 487 New: 487 Start: 479 End: 484 Max: 484
FAILED: Old: 487 New: 487 Start: 484 End: 489 Max: 489
FAILED: Old: 487 New: 487 Start: 489 End: 494 Max: 494
OK!
FAILED: Old: 503 New: 503 Start: 495 End: 500 Max: 500
FAILED: Old: 503 New: 503 Start: 500 End: 505 Max: 505
OK!
FAILED: Old: 517 New: 517 Start: 510 End: 515 Max: 515
FAILED: Old: 517 New: 517 Start: 515 End: 520 Max: 520
FAILED: Old: 517 New: 517 Start: 520 End: 525 Max: 525
OK!
FAILED: Old: 533 New: 533 Start: 526 End: 531 Max: 531
FAILED: Old: 533 New: 533 Start: 531 End: 536 Max: 536
OK!
FAILED: Old: 550 New: 550 Start: 541 End: 546 Max: 546
FAILED: Old: 550 New: 550 Start: 546 End: 551 Max: 551
FAILED: Old: 550 New: 550 Start: 551 End: 556 Max: 556
OK!

MSSQL не даст мне уникальную дату / время каждые 5 мс, смена 5 мс на 20 мс работает, но я не понимаю, почему 5 мс не работает. Надеюсь, что кто-то может прояснить это.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 06 октября 2011

Вот пара статей на эту тему, но в основном время Windows обновляется реже, чем через каждые 3,3 мс.

http://www.grahamwideman.com/gw/tech/dataacq/wintiming.htm

http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=85520

Есть также статья MSDN о точности GetTickCount:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408(v=vs.85).aspx

0 голосов
/ 06 октября 2011

Windows обновляет текущую дату / время только с циклом ~ 50 мс.

...