SQL Server トランザクション分離レベル(読込時のロック回避)

トランザクション分離レベルの制御

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
他のトランザクションでデーター更新中でも読み込みできる.
更新の途中で読み込んでしまう可能性があるので,例えば半分だけ更新されていて半分は更新されていないデーターを取得してしまうなど一貫性がないデーターになる場合がある(ダーティ リード).

SET TRANSACTION ISOLATION LEVEL READ COMMITTED
データー更新か終わるまで待ってから読み込む.
読み込み中に他でデーター更新することは可能.
SQL Serverの規定値.

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
データー更新か終わるまで待ってから読み込む.
読み込み中に他でデーター更新することはできない.
他で行を挿入することは可能.
必要なときだけ使う.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
データー更新か終わるまで待ってから読み込む.
読み込み中に他でデーター更新することはできない.
他で行を挿入することもできない.
どうしても必要なときだけ使う.

SQL Server 2005以降は以下のSNAPSHOTも使える.
これらは更新中も読み込みでき一貫性も保たれるが,
行サイズが大きく、更新の多いデータベースの場合は、
tempdb「Version Store」 の利用頻度増大や肥大化の悪影響がある.

(1)
READ_COMMITTED_SNAPSHOT ON
SELECTステートメント発行時点での正しいデーターを読み込む.
(ステートメント レベル)

(2)
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
トランザクション開始時点に存在したデーターを読み込む.
(トランザクション レベル)
ALLOW_SNAPSHOT_ISOLATION を ON に設定しておく必要がある.


参考:
SET TRANSACTION ISOLATION LEVEL (MSDN)
排他ロックにブロックされない読み取りの実現 (MS)
SQL Server でのスナップショット分離 (MSDN)

VB2005 DataTableのコピー

    Sub dtコピー()

        Dim dt As New DataTable
        dt.Columns.Add(“ID”, GetType(Integer))
        dt.Columns.Add(“名称”, GetType(String))

        dt.Rows.Add(0, “A”)
        dt.Rows.Add(1, “B”)
        dt.Rows.Add(2, “C”)

        ‘DataTable全体(構造と中身のデーター)をコピー
        Dim dt1 As DataTable
        dt1 = dt.Copy

       ‘DataTableの構造のみコピー
        Dim dt2 As DataTable
        dt2 = dt.Clone
        ‘1行ずつデーターをコピー
        For i As Integer = 0 To dt.Rows.Count – 1
            dt2.ImportRow(dt.Rows(i))
        Next

    End Sub

参考:
DataTable.Copy メソッド (MSDN)
DataTable.Clone メソッド (MSDN)
Visual Basic .NET を使用して DataTable 間で DataRow をコピーする方法 (MSDN)

VB2005 ジェネリックのリストの使い方

    Private Sub リストテスト()

        Dim a As New List(Of String)    ‘ジェネリックのリスト(文字列の例)
        Dim idx As Integer

        ‘リストに追加

        a.Add(“あ”)
        a.Add(“う”)
        a.Add(“い”)

        ‘リスト内に要素があるか調査(Containsメソッド)

        Dim str1 As String = “い”
        If a.Contains(“い”) Then
            MessageBox.Show(“い 発見”, “Containsメソッド”, MessageBoxButtons.OK)
        Else
            MessageBox.Show(“い 無し”, “Containsメソッド”, MessageBoxButtons.OK)
        End If

        ‘リスト内での要素の位置を調査(IndexOfメソッド)

        idx = a.IndexOf(“い”)
        If idx >= 0 Then
            MessageBox.Show(“い の位置=” + idx.ToString, “IndexOfメソッド”, MessageBoxButtons.OK)
        Else
            MessageBox.Show(“い 無し”, “IndexOfメソッド”, MessageBoxButtons.OK)
        End If

        ‘上記ContainsやIndexOfは要素数が大きいと遅い.
        ‘そんな時は要素数が大きくても速いBinarySearchを使う.
        ‘しかしBinarySearchはあらかじめソートされている必要がある.

        ‘リスト内での要素の位置を調査(BinarySearchメソッド)

        a.Sort() ‘ソートしないと結果がおかしくなる
        idx = a.BinarySearch(“い”)
        If idx >= 0 Then
            MessageBox.Show(“い の位置=” + idx.ToString, “BinarySearchメソッド”, MessageBoxButtons.OK)
        Else
            MessageBox.Show(“い 無し”, “BinarySearchメソッド”, MessageBoxButtons.OK)
        End If

        ‘BinarySearchその2
        ‘要素をソートしながら追加する方法
        ‘こうすると最初からソートされているのでSortメソッドを使う必要がない.

        a.Clear()

        idx = a.BinarySearch(“あ”)
        If idx < 0 Then
            idx = idx Xor -1
            a.Insert(idx, “あ”)
        End If

        idx = a.BinarySearch(“う”)
        If idx < 0 Then
            idx = idx Xor -1
            a.Insert(idx, “う”)
        End If

        idx = a.BinarySearch(“い”)
        If idx < 0 Then
            idx = idx Xor -1
            a.Insert(idx, “い”)
        End If

        idx = a.BinarySearch(“い”) ‘ソートされているので問題なし
        If idx >= 0 Then
            MessageBox.Show(“い の位置=” + idx.ToString, “BinarySearchその2”, MessageBoxButtons.OK)
        Else
            MessageBox.Show(“い 無し”, “BinarySearchその2”, MessageBoxButtons.OK)
        End If

    End Sub