簡言:
- 這篇文章我要談一談SQL Server分布式跨服務器查詢,多表Join,以及分布式事務的處理
SqlServer跨服務器查詢的方式
- 以往自己才疏學淺,學習了一波之后,在這記錄下來。
1. 使用sp_addlinkedserver和sp_addlinkedsrvlogin存儲過程添加linkserver和登錄
--別名 //ip地址 exec sp_addlinkedserver 'interlink','','SQLOLEDB', 'xxx.xxx.xx.xx' --別名 --登錄名 --密碼 exec sp_addlinkedsrvlogin 'interlink', 'false ',null, 'xxx', 'xxxxx' --注意:兩個別名要一致 --然后就可以通過以下方式進行聯合查詢: --上面的別名 --數據庫名 select * from [v3cdemo].[dbo].[AmmUnit] as ad1 right join interlink.[v3cdemo]. --表名 [dbo].[Address] as ad2 on ad1.unitID=ad2.AddressID --刪除某個linkserver exec sp_dropserver 'interlink ', 'droplogins '
運行效果如圖:
2. 使用openrowset函數
exec sp_configure 'show advanced options',1 go RECONFIGURE WITH OVERRIDE; --這里一定要加 with override 不然會出現不允許修改錯誤 exec sp_configure 'Ad Hoc Distributed Queries',1 go RECONFIGURE WITH OVERRIDE; --ip地址 --用戶名 --密碼 select * from openrowset( 'SQLOLEDB ', '192.168.0.12 '; 'sa'; '*bf123',[v3cdemo].[dbo].[Address]) --數據庫.表名 exec sp_configure 'Ad Hoc Distributed Queries',0 reconfigure exec sp_configure 'show advanced options',0 reconfigure --1. 有關 show advanced options的介紹請閱讀:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2005/ms188265(v=sql.90) --2. Ad Hoc Distributed Queries :分散式查詢。
- 運行結果如下:
3. 使用openquery函數
- openquery是基於linkserver實現的,得先添加一個linkserver
--別名 //ip地址 exec sp_addlinkedserver 'interlink','','SQLOLEDB', 'xxx.xxx.xx.xx' --別名 --登錄名 --密碼 exec sp_addlinkedsrvlogin 'interlink', 'false ',null, 'xxx', 'xxxxx' --使用openquery函數 select * FROM openquery(interlink, 'SELECT * FROM [v3cdemo].[dbo].[Address] ') --也可以把本地表導入到服務器表 --insert openquery(interlink, 'SELECT * FROM dbName.dbo.tableName ') select * from localTableName
運行結果如圖:
4. 使用opendatasource函數
SELECT * FROM opendatasource( 'SQLOLEDB ', 'Data Source=xxx.xxx.x.xx;User ID=xx;Password=xxx' ).[v3cdemo].[dbo].[Address] --[v3cdemo]:是數據庫名 --[dbo].[Address]:是表名 --Data Source=xxx.xxx.x.xx;User ID=xx;Password=xxx這個類似於我們的連接字符串,只是不需要指定數據庫。
運行結果如圖:
SqlServer分布式事務:
- .net framework:
- TransactionScpoe:TransactionScope是ADO.Net提供的事務機制(需要添加對system.transactioins程序集的引用),在普通ADO.Net代碼中也可以用、在Entity Framework、Dapper等ORM中也可以用;把相關需要事務處理的代碼用TransactionScope包裹起來即可,只要沒有Complete()的就會回滾
深入:
使用TransactionScope包圍的范圍,只要是同一個連接字符串創建的SqlConnection對象(MySQL等也支持),即使是多個Connection對象也會在一個事務中。
還支持嵌套事務,這個在開發大型系統中會涉及到,因為大型系統中一個方法會在很多地方被使用,一個方法有時候是自己獨立完成一件事情,有時候是被別人組合完成一件事。 TransactionScope可以嵌套, TransactionScope嵌套的情況,只有最外層的TransactionScope提交后所有的操作才會提交,否則所有操作都回滾。注意:如果在TransactionScope嵌套的范圍內出現多個不同連接字符串構成的Connection(比如同時連接多個同構或者異構的數據庫)則需要啟用MSDTC服務,否則會“MSDTC不可用”的異常,即使數據庫ip地址從127.0.0.1變成localhost甚至加上一個無關痛癢的空格都會要求啟用MSDTC服務。
- .net core:
- 因為.net core已經是跨平台了,而MSDTC服務是windows平台的東西,所以.net core 中的Transactionscope實現不包括對分布式事務的支持,因此不能使用 TransactionScope 或CommittableTransaction 來跨多個資源管理器協調。
- 可以使用 **Saga ** 來實現事務一致性:https://www.upyun.com/opentalk/310.html(saga只支持postpresql和mysql數據庫。偷懶)
- sage GitHub地址C#包:https://github.com/OpenSagas-csharp/servicecomb-pack-csharp