質問

We are trying to track down the cause of a performance problem.

We have a table with a single row that contains a primary key and a counter. Within a transaction we read the value of the counter, increment the value by one and save the new value.

The read and update is done using Entity Framework, we use a serializable transaction scope, we need to ensure that a counter value is read once only.

Most of the time this takes 0.1 seconds, then sometimes it takes over 1 second. We have not been able to find any pattern as to why this happen.

Has anyone else experienced variable performance when using transaction scope? Would it help to drop using transaction scope and set the transaction directly on the connection?

役に立ちましたか?

解決 2

We have now solved this problem.

The root of the problem was that the DB2 provider does not support transaction promotion. This results in Transaction Scope using MSDTC distributed transactions for everything.

We replaced the use of Transaction Scope with transactions set on the database connection.

Composite services that included the code in the question were then reduced from 3 seconds to 0.3 seconds.

他のヒント

I remember commenting on this question a long time ago, but recently some developers in my shop have started using TransactionScope, and have also run into performance issues. While trying to search for some information, this came up pretty high in the Google Search results.

The issue we ran into was that, apparently chaining commands (INSERTs, etc.) with BeginChain does not work when using a TransactionScope (at least on the version we are running, Client v9.7.4.4 connecting to DB2 z/OS v 10).

I thought that I would leave a workaround for the issue we ran into (slow performance when running lots [1k+] of INSERTs under TransactionScope, but ran fine when the scope was removed and chaining was allowed). I'm not really sure if it would help the original question directly, but there are some options if you look in the IBM.Data.DB2.dll classes that allow you to update rows using a DB2DataAdapter and an underlying DataTable.

Here's some example code in VB.NET:

Private Sub InsertByBulk(tableName As String, insertCollection As List(Of Object))
    Dim curTimestamp = Date.Now

    Using scope = New TransactionScope
        'Something that opens a connection to DB2, may vary
        Using conn = GetDB2Connection()
            'Dumb query to get DataTable from the ResultSet
            Dim sql = String.Format("SELECT * FROM {0} WHERE 1=0", tableName)

            Using adapter = New DB2DataAdapter(sql, conn)
                Using table As New DataTable
                    adapter.FillSchema(table, SchemaType.Source)

                    For Each item In insertCollection
                        Dim row = table.NewRow()
                        row("ID") = item.Id
                        row("CHAR_FIELD") = item.CharField
                        row("QUANTITY") = item.Quantity
                        row("UPDATE_TIMESTAMP") = curTimestamp
                        table.Rows.Add(row)
                    Next

                    Using bc = New DB2BulkCopy(conn)
                        bc.DestinationTableName = tableName
                        bc.WriteToServer(table)
                    End Using 'BulkCopy
                End Using 'DataTable
            End Using 'DataAdapter
        End Using 'Connection
        scope.Complete()
    End Using
End Sub
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top