我们正在尝试追查性能问题的原因。
我们有一个单行表,其中包含一个主键和一个计数器。在事务中,我们读取计数器的值,将值加一并保存新值。
读取和更新是使用实体框架完成的,我们使用可序列化的事务范围,我们需要确保只读取一次计数器值。
大多数情况下这需要 0.1 秒,有时则需要超过 1 秒。我们无法找到任何模式来解释为什么会发生这种情况。
在使用事务范围时,是否有其他人经历过可变性能?放弃使用事务范围并直接在连接上设置事务是否有帮助?
我们正在尝试追查性能问题的原因。
我们有一个单行表,其中包含一个主键和一个计数器。在事务中,我们读取计数器的值,将值加一并保存新值。
读取和更新是使用实体框架完成的,我们使用可序列化的事务范围,我们需要确保只读取一次计数器值。
大多数情况下这需要 0.1 秒,有时则需要超过 1 秒。我们无法找到任何模式来解释为什么会发生这种情况。
在使用事务范围时,是否有其他人经历过可变性能?放弃使用事务范围并直接在连接上设置事务是否有帮助?
记得很久以前评论过这个问题,但是最近我店里的一些开发者开始使用TransactionScope,也遇到了性能问题。在尝试搜索某些信息时,这在 Google 搜索结果中的排名很高。
我们遇到的问题是,显然使用BeginChain链接命令(INSERT 等)在使用TransactionScope时不起作用(至少在我们正在运行的版本上,客户端 v9.7.4.4 连接到 DB2 z/OS v 10 )。
我认为我会为我们遇到的问题留下一个解决方法(在 TransactionScope 下运行大量 [1k+] 的 INSERT 时性能缓慢,但在删除范围并允许链接时运行良好)。我不确定它是否会直接帮助原始问题,但是如果您查看允许您使用 DB2DataAdapter 和底层 DataTable 更新行的 IBM.Data.DB2.dll 类,则有一些选项。
以下是 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
我们现在已经解决了这个问题。
问题的根源在于 DB2 提供者不支持事务提升。这导致事务范围使用 MSDTC 分布式事务处理所有内容。
我们将事务范围的使用替换为在数据库连接上设置的事务。
包含问题中代码的复合服务然后从 3 秒减少到 0.3 秒。