2012-12-20 12 views
5

यह सुनिश्चित करने के लिए कि निम्नलिखित विवरण एक ट्रांसकेशन में चल रहे हैं?एकाधिक आमंत्रण-एसक्यूएलएमएमडी और एसक्यूएल सर्वर लेनदेन

try 
{ 
    Invoke-SqlCmd -Query 'begin tran; ...sql script...' 
    # Other Powershell script 
    Invoke-SqlCmd -Query '...sql script...; if @@transcation > 0 commit tran' 
} 
catch 
{ 
    Invoke-SqlCmd -Query 'if @@transaction > 0 rollback tran;' 
} 

लेनदेन में पावरशेल स्क्रिप्ट चलाने का सबसे अच्छा तरीका क्या है?

+0

PowerShell:

प्रतिबद्ध अपने दायरे के लिए का उपयोग कर, तो एक काम कर उदाहरण के लिए प्रतिबद्ध पूरा तो तरह के बाद एक स्पष्ट निपटाने जोड़ने होगा सुनिश्चित करने के लिए अंत पर निष्पादित किया जाता है स्टार्ट-ट्रांजैक्शन है, क्या आप इसका जिक्र कर रहे हैं? http://technet.microsoft.com/en-us/library/hh849772.aspx –

+0

@ShawnMelton नहीं, मैंने 'स्टार्ट-ट्रांजैक्शन' की कोशिश की; Invoke-Sqlcmd '## परीक्षण में 1 का चयन करें' -सेवर इंस्टेंस माइसेवर; पूर्व-लेनदेन' और यह अभी भी तालिका बनाई गई है। – ca9163d9

उत्तर

2

Invoke-sqlcmd ADO.NET ट्रांसकेशंस का समर्थन नहीं करता है। आप दो तरीके दिए है, या तो ADO.NET लेनदेन के लिए इस MSDN प्रलेखीकरण में दिखाया गया है सी # कोड के बराबर Powershell कोड लिखें: http://msdn.microsoft.com/en-us/library/2k2hy99x(v=vs.110).aspx

या T-SQL लेनदेन का उपयोग करें। टी-एसक्यूएल को जोड़ने के बिना इसे करने का एक त्वरित तरीका प्रत्येक स्क्रिप्ट को आज़माएं/पकड़ना XACAT_ABORT चालू करना है; फिर शुरूआत में स्क्रिप्ट लपेटें और लेनदेन करें। ध्यान रखें कि यह त्रुटियों को समाप्त पकड़ नहीं सकता है:

http://msdn.microsoft.com/en-us/library/ms188792.aspx

4

दुर्भाग्य से, PowerShell में SqlProviderRegistry प्रदाता की तरह लेन-देन क्षमता नहीं है। इसलिए Start-transaction यहां काम नहीं करेगा।

आप मूल जा सकते हैं और TransactionScope कक्षा का उपयोग कर सकते हैं।

Try{ 
    $scope = New-Object -TypeName System.Transactions.TransactionScope 

    Invoke-Sqlcmd -server Darknite -Database AdventureWorks2008 -Query $Query1 -ea stop 
    Invoke-Sqlcmd -server Darknite -Database AdventureWorks2008 -Query $Query2 -ea stop 

    $scope.Complete() 
} 
catch{ 
    $_.exception.message 
} 
finally{ 
    $scope.Dispose() 
} 

सभी आह्वान-sqlcmds जो $ गुंजाइश असाइनमेंट और $scope.complete() के बीच रखा जाता है, एक लेन-देन के रूप में माना जाएगा। अगर उनमें से कोई भी गलती करता है, तो सभी को वापस लुढ़काया जाएगा।

Install-Module -Name InvokeQuery 

आप स्पष्ट रूप से वापस रोल करने के लिए एक त्रुटि तब होती है, तो जरूरत नहीं है:

0

मैं हाल ही में डेटाबेस के साथ बातचीत के लिए एक नया मॉड्यूल है कि लेन-देन का समर्थन करता है प्रकाशित किया। Start-Transaction के साथ बनाया गया परिवेश लेनदेन आपके लिए इसका ख्याल रखेगा।

try { 
    $db = "test" 
    Start-Transaction 

    $sql = "insert into table1 values (NEWID(), 8765, 'transactions!', GETDATE())" 
    $rowcount = $sql | Invoke-SqlServerQuery -Database $db -UseTransaction -CUD -Verbose 
    Write-Host "Inserted $rowcount rows!" 

    $sql = "insert into table1 values (NEWID(), 5555, 'transaction too!', GETDATE())" 
    $rowcount = $sql | Invoke-SqlServerQuery -Database $db -UseTransaction -CUD -Verbose 
    Write-Host "Inserted $rowcount rows!" 

    Complete-Transaction 
} 
catch { 
    ##Transaction will automatically be rolled back.... 
    Write-Error $_ 
} 

आप स्पष्ट रूप से लेन-देन के भीतर वापस रोल करना चाहते हैं तो एक त्रुटि फेंक:

throw 'rollback because of reason X!' 

अधिक उदाहरण: https://github.com/ctigeek/InvokeQueryPowershellModule/blob/master/README.md#transactions

2

नितेश एक बहुत अच्छा उदाहरण देता है, मुझे मदद की, धन्यवाद ! जोड़ने की एक बात यह है कि Scope.Complete() डेटाबेस को लेनदेन प्रतिबद्ध नहीं भेजता है। यदि आप इस कोड का उपयोग लूप में करते हैं तो यह स्पष्ट होगा।

$scope.Complete(); 
$scope.Dispose(); 

विवरण देखें TransactionScope Complete() doesn't commit the transaction before exiting the USING statement

संबंधित मुद्दे