【问题标题】:Please help prevent data layer refactoring of this ODP.NET code and transactions请帮助防止此 ODP.NET 代码和事务的数据层重构
【发布时间】:2009-08-29 18:17:00
【问题描述】:

我正在使用带有 ODP.NET 的 Oracle 11g 客户端。我正在尝试添加条件事务处理。

Dim ds As New DataSet()
Dim txn As OracleTransaction
Dim _beginTransaction as Bolean = true
 Using conn As New OracleConnection(ConnString)
            Try
                conn.Open()
                If _beginTransaction Then
                        txn = conn.BeginTransaction(IsolationLevel.Serializable)
                End If

                Dim adapter As OracleDataAdapter = New OracleDataAdapter()
                adapter.SelectCommand = New OracleCommand(sSQL, conn)

                For i As Integer = 0 To UBound(parameters, 1)
                    adapter.SelectCommand.Parameters.Add(parameters(i))
                Next

                adapter.Fill(ds)
                If _beginTransaction Then
                    txn.Commit() //txn is undefined here? why?
                End If


            Catch e As Exception
                txn.Rollback()
            End Try
        End Using

如何修复 txn 为空/空?错误是:变量“txn”在被赋值之前被使用。运行时可能会导致空引用异常。链接或指向解决方案的指针也将不胜感激。

编辑:感谢 RichardOD 指出您不能明确声明不能通过 ODP.NET 在存储过程上打开事务。我已经验证这是一个问题。但是我们仍然没有弄清楚为什么会发生错误。我知道 txn 最初在 if 语句中被赋予了一个值,但是在 try/catch 块之外定义应该使这无关紧要......对吗?还是编码不好?

【问题讨论】:

    标签: vb.net oracle odp.net


    【解决方案1】:

    假设 _beginTransaction 是一个布尔值,您是否在 If _beginTransaction Then 之前将其设置为 true ?

    在开始这个之前你是否已经提交了上一个事务? Oracle 可以通过连接池和BeingTransaction 做一些奇怪的事情。

    很久以前我有一个类似的错误。 Have you looked here?

    编辑-您是否尝试调用 .NET 存储过程? OracleConnection.BeginTransactiondoes not support stored procedure calls:

    OracleConnection.BeginTransaction 是 .NET 存储过程不允许

    【讨论】:

    • 在应用中,第二次调用这个方法就是第一次打开事务。 using 语句还应该处理连接。 . .对吗?
    • 如果连接是池化的(很可能是),那就是问题开始的时候。尚未提交的旧连接上的新事务...
    • 第一次调用数据库是一个选择,没有声明隐式事务。 . .
    • 尝试在连接字符串中设置 Pooling=false 看看你还是有同样的问题(显然不要让这个打开)
    • Pooling=false 没有改变任何东西。 . . .
    【解决方案2】:

    问题:分配后是否立即为空?如果不是,它什么时候变为空?如果它立即为空,则可能是连接池的东西。如果从 conn 得到适配器或者填充之后,那就更疯狂了……

    但我会尝试找出答案

    【讨论】:

    • 不,那是让我摸不着头脑的部分。 . .它确实有一个值并被赋值。 . . .
    • 所以只有当你提交时它才会被分配?肯定是事先在某个地方发生的。
    • 不,我知道。 . .添加手表并逐步执行代码(再次:()步骤到 txn.Commit() ->在 VS 中点击 f-10,落到 Catch 块,异常为空
    • 好吧,在与 GetOracleDecimal 中的内存泄漏(在我们提供给客户的代码中)斗争一年多之后,我们开始不信任 ODP(.Net 2.0)......祝你好运!
    • 如果错误是“运行时可能导致空引用异常”,请稍候。这是一个编译错误,是因为你的赋值是一个 IF 子句。
    【解决方案3】:

    Oracle 不需要事务来选择数据。为什么要尝试打开一个?

    编辑:
    如果您的 vb 代码是从 oracle 调用的(通过 .net 集成),那么就像 RichardOD 所写的那样,没有事务支持。请说明环境。

    执行的sql语句是动态的,在sSQL中给出。该命令已准备好并提供给填充 DataSet 的 DataAdapter。比你只能执行 SELECT 语句。否则没有结果。

    因为参数也准备好了。您正在调用存储过程(没有告诉 CommandType 是 StoredProcedure)。您的参数之一是将提取到数据集中的引用游标参数。对吧?

    Oracle 不像 sql server 那样需要显式事务。 Oracle 使用会话中的第一个 dml 语句启动一个隐式事务。副作用是,如果您没有启动事务,则无法提交隐式事务。不知道有没有通过连接对象访问隐式事务。

    【讨论】:

    • 好问题。从技术上讲,这是一个正在执行的过程。我正在重构数据层。
    • @andrewWinn-如果您使用的是存储过程,我已经更新了我的答案以解释这不起作用。
    • @andrewWinn:这个从plsql调用的vb代码是否集成到数据库中?您是否在隐式连接上运行?我有点困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2021-05-05
    • 2011-11-17
    • 2013-12-22
    相关资源
    最近更新 更多