簡體   English   中英

跨鏈接Oracle服務器的SQL Server和WCF事務

[英]SQL Server and WCF Transactions across Linked Oracle Servers

注意請參閱更新6.它有一個簡單的應用程序,演示如何重新創建問題。

我是DTC的噩夢......我們的設置是我們有兩個數據庫; 一個SQL Server 2008數據庫和一個Oracle數據庫(11g,我相信)。 我已經安裝了oracle MTS的東西。 我將DTC配置為允許分布式事務。 對Oracle表的所有訪問都通過SQL Server數據庫中與鏈接服務器中的Oracle表相對的視圖進行。

(關於DTC配置:選中 - >網絡DTC訪問,允許遠程客戶端,允許入站,允許出站,相互身份驗證(嘗試所有3個選項),啟用XA事務和啟用SNA LU 6.2事務.DTC以NT AUTHORITY\\NetworkService登錄NT AUTHORITY\\NetworkService

我們的應用程序是一個ASP.NET MVC 4.0應用程序,它調用許多WCF服務來執行數據庫工作。 目前,Web應用程序和WCF服務共享相同的應用程序池(不確定它是否相關,但以防萬一...)

我們的一些服務是交易性的,有些則不是。

事務性的每個WCF服務在其接口上都具有以下屬性:

[ServiceContract(SessionMode=SessionMode.Required)]

以及界面中方法簽名的以下屬性:

[TransactionFlow(TransactionFlowOption.Allowed)]

以及每個方法實現的以下屬性:

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]

在我的數據訪問層中,所有事務方法都設置如下:

using (IDbConnection conn = DbTools.GetConnection(_configStr, _connStr, true))
{
    using (IDbCommand cmd = DbTools.GetCommand(conn, "SET XACT_ABORT ON"))
    {
        cmd.ExecuteNonQuery();
    }
    using (IDbCommand cmd = DbTools.GetCommand(conn, sql))
    {
       ... Perform actual database work ...
    }
}

作為事務性調用事務DAL代碼的服務。 我們的想法是將需要交易的東西(少數情況)與不需要交易的東西(約95%的情況)分開。

不應該在事務中調用事務性和非事務性WCF方法(盡管我沒有驗證這一點,這可能是我遇到問題的原因。我不確定,這是我為什么的一部分'我問這里。)

正如我之前提到的,在大多數情況下,這一切都很好。

我不知道是什么時候啟動它,我開始得到錯誤。 一旦他們開始,幾乎一切都開始失敗了一段時間。 最終事情又開始了。 不知道為什么......這都是在一個用戶的測試環境中。

有時錯誤是:

無法為鏈接服務器“ORACLSERVERNAME”的OLE DB提供程序“OraOLEDB.Oracle”啟動嵌套事務。 由於XACT_ABORT選項設置為OFF,因此需要嵌套事務。

這個消息,我猜是當我在事務中有非事務性的東西時正在發生,因為我沒有在非事務性代碼中設置XACT_ABORT (這完全可行,如果這將解決我的問題)。

但是,大多數情況下,錯誤是這樣的:

System.Data.SqlClient.SqlException(0x80131904):無法執行操作,因為鏈接服務器“ORACLSERVERNAME”的OLE DB提供程序“OraOLEDB.Oracle”無法啟動分布式事務。

現在,最初我們只有SQL Server表上的事務,並且一切正常。 直到我們為某些Oracle表添加了事務支持才開始失敗。 我知道Oracle事務有效。 正如我所說,大多數時候,一切都只是笨拙的,然后有時它開始失敗並且一直失敗,直到它決定停止失敗然后它再次起作用。

希望我能弄清楚如何將其作為“功能”出售給我的用戶,但我並不樂觀,所以我很樂意幫助您追蹤它。 如果我遺漏了任何重要信息,請告訴我。

更新1:我注意到我們的事務似乎沒有設置DistributedIdentifier,所以我在這篇博文中添加了EnsureDistributed()方法: http//www.make-awesome.com/2010/04/forcibly-creating -a分布式凈交易/

而不是硬編碼的Guid(這似乎會導致很多問題),我讓它為每個事務生成一個新的Guid,這似乎有效,但它沒有解決我的問題。 我想知道是否缺乏DistribuedIdentifier指示其他一些潛在的問題。 我以前從未處理過這樣的環境,所以我不確定什么是“正常”。

更新2:我注意到DistributedIdentifier沒有傳遞給WCF。 從客戶端,我在Transaction.Current.TransactionInformation中有一個DistributedIdentifier和一個LocalIdentifier。 然而,在WCF服務器中,只有一個LocalIdentifier集,它與客戶端的Guid不同(這是有意義的,但我希望DistributedIdentifier可以通過)。

更新3:似乎當我處於事務中失敗時,即使在我關閉IIS之后,我也無法讓DTC服務關閉並重新啟動。 例如,如果我進入組件服務並更改安全設置,然后單擊“應用”或“確定”,等待一段時間后,我會收到一條撥號,指出“未能重新啟動MS DTC服務。請查看事件日志以獲取更多詳細信息“。

在事件日志中,我得到了一系列事件:

1 (from MSDTC): "The MS DTC service is stopping"
2 (From MSSQL$SQLEXPRESS): "The connection has been lost with Microsoft Distributed Transaction 
                            Coordinator (MS DTC). Recovery of any in-doubt distributed transactions 
                            involving Microsoft Distributed Transaction Coordinator (MS DTC) 
                            will begin once the connection is re-established. This is an 
                            informational message only. No user action is required."
-- Folowed by these 3 identical messages
3 (from MSDTC Client 2): 'MSDTC encountered an error (HR=0x80000171) while attempting to establish a secure connection with system GCOVA38.'
4 (from MSDTC Client 2): 'MSDTC encountered an error (HR=0x80000171) while attempting to establish a secure connection with system GCOVA38.'
5 (from MSDTC Client 2): 'MSDTC encountered an error (HR=0x80000171) while attempting to establish a secure connection with system GCOVA38.'
6 (From MSDTC 2): MSDTC started with the following settings:
                     Security Configuration (OFF = 0 and ON = 1):
                     Allow Remote Administrator = 0,
                     Network Clients = 1,
                     Trasaction Manager Communication: 
                     Allow Inbound Transactions = 1,
                     Allow Outbound Transactions = 1,
                     Transaction Internet Protocol (TIP) = 0,
                     Enable XA Transactions = 1,
                     Enable SNA LU 6.2 Transactions = 1,
                     MSDTC Communications Security = Mutual Authentication Required,
                     Account = NT AUTHORITY\NetworkService,
                     Firewall Exclusion Detected = 0
                     Transaction Bridge Installed = 0
                     Filtering Duplicate Events = 1

這讓我想知道是否有什么東西可能會讓交易在某個地方開放? 我覺得有一種感覺,因為缺乏更好的術語,“懸空交易”沒有得到承諾或回滾。 在我使用TransactionScope的每種情況下,它都發生在“使用”語句中,所以一切都應該回滾或提交。 但我真的開始認為某種程度上有些東西在泄漏...

更新4:與更新3相關。我正在執行手動登記。 我們的連接字符串有“Enlist = false”。 DBTools.GetConnection()接受一個布爾參數,該參數指定是否將當前事務登記到連接中。 我發布此更新是因為,基於Update 3中的內容,我想知道,或許,不應該招募交易的連接是否以某種方式招募它們。

public static IDbConnection GetConnection(string configString, string connectionString, bool enlistTransaction)
{
    SqlConnection conn = new SqlConnection(connectionString);
    conn.Open();
    if (enlistTransaction && Transaction.Current != null)
    {
        conn.EnlistTransaction(Transaction.Current);
    }
    return conn;
}

public static IDbCommand GetCommand(IDbConnection conn, string command)
{
    IDbCommand cmd = conn.CreateCommand();
    cmd.CommandText = command;
    return cmd;
}

更新5:我設法找到一組單元測試,如果我運行該組,它總是在同一個測試中的同一個地方失敗(但如果我只是自己運行該測試,一遍又一遍,它不會不會失敗。它與之前運行的測試有關。)我設法獲得了一些DTC跟蹤日志。 這是一個顯示初始失敗事務的日志。 我也在展示一些先前的交易,以防看到一些有意義的交易有所幫助。 失敗的交易從seq=1846開始。

pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.064   ;seq=1822       ;eventid=TRANSACTION_BEGUN                        ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"transaction has begun, description :'<NULL>'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.064   ;seq=1823       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #1. RM guid = '344d3060-811c-4fc6-bab6-0eea76e3af3a'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.064   ;seq=1824       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #2. RM guid = '7b16851c-00a5-41dd-b59c-b003dcae08ec'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.064   ;seq=1825       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1005 enlisted as transaction enlistment #3. RM guid = '72efe9cc-80f2-4a5b-9659-28b07987b600'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.079   ;seq=1826       ;eventid=RECEIVED_COMMIT_REQUEST_FROM_BEGINNER    ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"received request to commit the transaction from beginner"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.079   ;seq=1827       ;eventid=RM_ISSUED_PREPARE                        ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"prepare request issued to resource manager #1004 for transaction enlistment #1"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.079   ;seq=1828       ;eventid=RM_ISSUED_PREPARE                        ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"prepare request issued to resource manager #1004 for transaction enlistment #2"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.079   ;seq=1829       ;eventid=RM_ISSUED_PREPARE                        ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"prepare request issued to resource manager #1005 for transaction enlistment #3"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1830       ;eventid=RM_VOTED_COMMIT                          ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 voted commit for transaction enlistment #2"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1831       ;eventid=RM_VOTED_COMMIT                          ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 voted commit for transaction enlistment #1"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1832       ;eventid=RM_VOTED_READ_ONLY                       ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"resource manager #1005 voted read-only for transaction enlistment #3"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1833       ;eventid=TRANSACTION_COMMITTED                    ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"transaction has got committed"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1834       ;eventid=RM_ISSUED_COMMIT                         ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"commit request issued to resource manager #1004 for transaction enlistment #1"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1835       ;eventid=RM_ISSUED_COMMIT                         ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"commit request issued to resource manager #1004 for transaction enlistment #2"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1836       ;eventid=RM_ACKNOWLEDGED_COMMIT                   ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of commit request from the resource manager #1004 for transaction enlistment #1"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.079   ;seq=1837       ;eventid=RM_ACKNOWLEDGED_COMMIT                   ;tx_guid=49a79b73-66c0-48cb-abb1-8b657a2e3e4d     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of commit request from the resource manager #1004 for transaction enlistment #2"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.002   ;seq=1838       ;eventid=TRANSACTION_BEGUN                        ;tx_guid=55dd8607-c01e-4135-a247-7ef435c70bc6     ;"TM Identifier='(null)                                            '" ;"transaction has begun, description :'<NULL>'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.018   ;seq=1839       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=55dd8607-c01e-4135-a247-7ef435c70bc6     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #1. RM guid = '7b16851c-00a5-41dd-b59c-b003dcae08ec'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.018   ;seq=1840       ;eventid=RECEIVED_COMMIT_REQUEST_FROM_BEGINNER    ;tx_guid=55dd8607-c01e-4135-a247-7ef435c70bc6     ;"TM Identifier='(null)                                            '" ;"received request to commit the transaction from beginner"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:45.018   ;seq=1841       ;eventid=TRANSACTION_COMMITTED                    ;tx_guid=55dd8607-c01e-4135-a247-7ef435c70bc6     ;"TM Identifier='(null)                                            '" ;"transaction has got committed"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.106   ;seq=1842       ;eventid=TRANSACTION_BEGUN                        ;tx_guid=cc4a8215-3475-4c14-b40d-d150fc79f8f7     ;"TM Identifier='(null)                                            '" ;"transaction has begun, description :'<NULL>'"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.121   ;seq=1843       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=cc4a8215-3475-4c14-b40d-d150fc79f8f7     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #1. RM guid = '7b16851c-00a5-41dd-b59c-b003dcae08ec'"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.121   ;seq=1844       ;eventid=RECEIVED_COMMIT_REQUEST_FROM_BEGINNER    ;tx_guid=cc4a8215-3475-4c14-b40d-d150fc79f8f7     ;"TM Identifier='(null)                                            '" ;"received request to commit the transaction from beginner"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:45.121   ;seq=1845       ;eventid=TRANSACTION_COMMITTED                    ;tx_guid=cc4a8215-3475-4c14-b40d-d150fc79f8f7     ;"TM Identifier='(null)                                            '" ;"transaction has got committed"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.657   ;seq=1846       ;eventid=TRANSACTION_BEGUN                        ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"transaction has begun, description :'<NULL>'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.657   ;seq=1847       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #1. RM guid = '344d3060-811c-4fc6-bab6-0eea76e3af3a'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1848       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"resource manager #1004 enlisted as transaction enlistment #2. RM guid = '7b16851c-00a5-41dd-b59c-b003dcae08ec'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1849       ;eventid=RM_ENLISTED_IN_TRANSACTION               ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"resource manager #1005 enlisted as transaction enlistment #3. RM guid = '72efe9cc-80f2-4a5b-9659-28b07987b600'"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1850       ;eventid=RECEIVED_ABORT_REQUEST_FROM_NON_BEGINNER ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"received request to abort the transaction from non beginner"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1851       ;eventid=TRANSACTION_ABORTING                     ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"transaction is aborting"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1852       ;eventid=RM_ISSUED_ABORT                          ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"abort request issued to resource manager #1004 for transaction enlistment #1"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1853       ;eventid=RM_ISSUED_ABORT                          ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"abort request issued to resource manager #1004 for transaction enlistment #2"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1854       ;eventid=RM_ISSUED_ABORT                          ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"abort request issued to resource manager #1005 for transaction enlistment #3"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1855       ;eventid=RM_ACKNOWLEDGED_ABORT                    ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of abort request from the resource manager #1005 for transaction enlistment #3"
pid=1244       ;tid=6284       ;time=10/15/2013-10:00:59.672   ;seq=1856       ;eventid=RM_ACKNOWLEDGED_ABORT                    ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of abort request from the resource manager #1004 for transaction enlistment #2"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:59.672   ;seq=1857       ;eventid=RM_ACKNOWLEDGED_ABORT                    ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"received acknowledgement of abort request from the resource manager #1004 for transaction enlistment #1"
pid=1244       ;tid=8488       ;time=10/15/2013-10:00:59.672   ;seq=1858       ;eventid=TRANSACTION_ABORTED                      ;tx_guid=d07cc436-033c-450b-a36c-7e2fe79cdb81     ;"TM Identifier='(null)                                            '" ;"transaction has been aborted"

我不確定,但值得注意的是,在上一次交易完成和這次交易開始之間有14.5秒的延遲。 單元測試似乎掛在那里,我還沒弄清楚原因。

這可能無關緊要,但失敗在下面的ExecuteNonQuery中:

public IClientInternal GetClient(string clientCode)
{
    string sql = "SELECT [CLIENT_CODE], [COMPANY], [EMPLOYEE] << more fields here >> FROM  OPENQUERY("+
                    _settings.LinkedOracleServer + ", 'SELECT * FROM CLIENT WHERE "+ 
                    "CLIENT_CODE = ''" + clientCode + "'' "+
                    "')";

    using (IDbConnection conn = DbTools.GetConnection(_configStr, _connStr, true))
    {
        using (IDbCommand cmd = DbTools.GetCommand(conn, "SET XACT_ABORT ON"))
        {
            cmd.ExecuteNonQuery();
        }
        using (IDbCommand cmd = DbTools.GetCommand(conn, sql))
        {
            DbTools.AddParameter(cmd, "@CLIENT_CODE", DbType.String, clientCode);
            IDataReader reader = cmd.ExecuteReader();
            if (reader.Read())
            {
                return ClientInternal.FromReaderRecord(reader);
            }
            return null;
        }
    }
}

在最終失敗之前,此代碼會成功調用多次。

我想知道的是,如果有可能在Oracle方面沒有正確清除trasnactions。 如果我理解正確,Oracle有10個分布式事務限制。 它是否有可能認為以前的分布式交易仍然是開放的(我沒有看到任何跡象。所有證據似乎都表明所有以前的交易都在完美運行,而DTC日志顯示它們已被提交)。

更新6:我設法用相當小的代碼產生問題。 下面,除了更改DB和clientCode的名稱之外,是重現問題的確切代碼。 我得到一個SqlExceptioncmd.ExecuteReader()的調用GetClients() The operation could not be performed because OLE DB provider "OraOLEDB.Oracle" for linked server "ORACLE" was unable to begin a distributed transaction. 我可以GetEmployeeBadges()調用GetEmployeeBadges() ,它會起作用。 我可以一遍又一遍地調用GetClients() ,它會工作。 但是,如果我調用GetEmployeeBadges()然后在transcaction中調用GetClients() ,它將失敗。 它似乎是在交易中登記第二個電話的結果。

另外需要注意的是, GetEmployeeBadges()似乎有些奇怪。 這是我們環境的另一個奇怪之處,但V_EMPLOYEE和V_PAEMPLOYEE實際上是另一個Oracle數據庫的視圖。 所以我遇到的Oracle服務器在另一台Oracle服務器上有視圖。 所以這是一個oracle表的oracle視圖的SQL Server視圖。 我知道,這有點瘋狂。 這里的任何功能都令人驚嘆。 如果我嘗試在事務中運行GetEmployeeBadges()並在事務中登記它,它實際上將失敗: Cannot execute the query "<<query text here>>" against OLE DB provider "OraOLEDB.Oracle" for linked server "ORACLE".

我無法想象這會讓這一點變得更小。

class Program
{
    private static string connStr = @"Server=localhost\SQLEXPRESS;Database=MYDB;Trusted_Connection=True;Enlist=false";
    static void Main(string[] args)
    {
        GetEmployeeBadges();

        using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 15, 0)))
        {
            GetClients();
            ts.Complete();
        }
    }

    private static void GetEmployeeBadges()
    {
        string sql = @"select * from OPENQUERY(ORACLE, 'select a.security_nbr, a.employee, b.last_name, b.first_name, b.department
                        from V_PAEMPLOYEE a, V_EMPLOYEE b
                        where 
                        LENGTH(TRIM(a.SECURITY_NBR)) > 0 and
                        a.EMPLOYEE = b.EMPLOYEE and
                        a.COMPANY = 3')";        
        using (IDbConnection conn = DbTools.GetConnection(connStr))
        {
            using (IDbCommand cmd = DbTools.GetCommand(conn, "SET XACT_ABORT ON"))
            {
                cmd.ExecuteNonQuery();
            }
            using (IDbCommand cmd = DbTools.GetCommand(conn, sql))
            {
                cmd.CommandTimeout = 240;
                IDataReader reader = cmd.ExecuteReader();
            }
        }
    }

    public static void GetClients()
    {
        string clientCode = "clientCode";
        string sql = @"SELECT [CLIENT_CODE], [COMPANY], [EMPLOYEE], [MENU_TOKEN_CODE], [ADMINISTRATOR_FLAG], [SUPERVISOR_FLAG], 
                              [CLIENT_DESCR], [DEFAULT_QUEUE_CODE], [FG_WHSE_CODE], [FRT_WHSE_CODE], [BILL_COMP_CODE], [FI_COMP_CODE], 
                              [DEFAULT_ROLE], [DEFAULT_PRINTER_CODE], [SHIP_PRINTER_CODE], [DEFAULT_DISPLAY] 
                       FROM  OPENQUERY( ORACLE, 'SELECT * FROM CLIENT WHERE CLIENT_CODE = ''clientCode''')";

        using (IDbConnection conn = DbTools.GetConnection(connStr, true))
        {
            using (IDbCommand cmd = DbTools.GetCommand(conn, "SET XACT_ABORT ON"))
            {
                cmd.ExecuteNonQuery();
            }
            using (IDbCommand cmd = DbTools.GetCommand(conn, sql))
            {
                DbTools.AddParameter(cmd, "@CLIENT_CODE", DbType.String, clientCode);
                IDataReader reader = cmd.ExecuteReader();
                reader.Read();
            }
        }
    }
}

DbTools的東西,萬一它有用的是:

public static class DbTools
{
    public static IDbConnection GetConnection(string connectionString)
    {
        return GetConnection(connectionString, false);
    }

    public static IDbConnection GetConnection(string connectionString, bool enlistTransaction)
    {
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
        if (enlistTransaction && Transaction.Current != null)
        {
            conn.EnlistTransaction(Transaction.Current);
        }
        return conn;
    }

    public static IDbCommand GetCommand(IDbConnection conn, string command)
    {
        IDbCommand cmd = conn.CreateCommand();
        cmd.CommandText = command;
        return cmd;
    }

    public static IDbDataParameter AddParameter(IDbCommand cmd, string name, DbType type, object value)
    {
        IDbDataParameter param = cmd.CreateParameter();
        param.ParameterName = name;
        param.DbType = type;
        param.Value = value != null ? value : DBNull.Value;
        cmd.Parameters.Add(param);
        return param;
    }
}

獎金還剩23個小時。 我願意給那150分給那個人!!!

根據KB187289 ,Oracle不支持嵌套事務,因此只要事務在沒有干凈回滾的情況下中止,就會出現第一條錯誤消息。 在這種情況下,數據庫都不能完成事務,並且將停止,直到阻止事務被丟棄。

XACT_ABORT強制事務在第一個運行時錯誤時終止並執行立即回滾。 為所有連接激活XACT_ABORT以便立即拋出運行時錯誤,其中一個可能導致事務在任一數據庫上失敗。

如果沒有XACT_ABORT ,MS SQL服務器會嘗試在嵌套事務中對已損壞的查詢進行靜默,部分回滾。 運行時錯誤將被抑制,除非明確捕獲,否則將被忽略。

這不能解決您的原始問題(仍然存在失敗的事務),但它使您能夠首先看到運行時錯誤。

TRY...CATCH和嵌套事務將是自SQL 2005以來執行正確錯誤處理的更簡潔方法,但由於Oracle不支持這些語言擴展,因此不適合您。

這個問題是由我們非常奇怪的設置引起的。

我們有一個具有鏈接Oracle服務器的SQL Server。 我們在SQL Server中為Oracle服務器上的表創建視圖。 Oracle服務器中有一些視圖是對另一個Oracle服務器中的表的視圖。 我們只是在服務器2中的Oracle表上的服務器1中的Oracle視圖的SQL服務器中創建視圖。即使我們在從視圖的視圖中獲取數據時沒有使用事務,也導致后續執行中的事務失敗(如果有人關心如何做到這一點,我會喜歡解釋。)

我們的解決方案是簡單地創建第二個鏈接服務器並繞過視圖的視圖。 你可能想知道我們為什么不開始這樣做,這只是因為,直到我們遇到這個問題,沒有令人信服的理由有第二個鏈接服務器(並且第二個服務器上有非常敏感的信息,所以我們喜歡最小化訪問它的路徑的想法)。 顯然,我們現在有一個令人信服的理由。

雖然我沒有給出Exth3的答案,但我確實給了他/她提供最終導致我發現問題的信息的賞金點。 謝謝Exth3!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM