服务器设置分布式事务(数据库开启分布式事务)

  • Post author:
  • Post category:其他



分布式事务方案

一、

概述(分布式事务)

二、 分布式事务的注意项

  1. 事务尽可能短。

减少事务占用数据的时间,减短其他访问者等待时间。

  1. 事务隔离级别

三、

分布式事务基础设置


分布式事务基础设置是比较繁琐的,也是很容易出问题的一个环节,大体上从三方面入手。三方面首拼字母为

SFM,我们所需要设置的正是SFM。

S:数据库

F:防火墙


添加

msdtc到防火墙列外。

M:MSDTC分布式事务处理协调器

主意事项:(故障排查)

  1. 检测端口


数据库端口:

1433

RPC服务通讯端口:135

telnet +IP+端口号

例如:telnet 192.168.1.64 135


  1. 检查

    NetBIOS 名称是否解析IP 地址

NetBIOS 名称:



Network Basic Input/Output System的简称,一般指用于局域网通信的一套API

NetBIOS 名称是称作“完整计算机名称”的名称的第一部分,例如,如果“完整计算机名称”为 myserver.company.domain.com,则计算机的 NetBIOS 名称为 myserver


检测方法:

1)在客户端计算机上启动命令提示符,键入以下命令,然后按Enter: ping <NetBIOS name of server computer>

ping命令的记过应该返回与服务器计算机相关联的IP。

2)在服务器计算机上启动命令提示符,键入以下命令,然后按Enter: ping <NetBIOS name of client computer>

ping命令的记过应该返回与客户端计算机相关联的IP。


如果

NetBIOS 名称解析在任何一个方向上不成功,或者反向名称查找失败,请在 DNS 服务器、NetBIOS 名称服务器、HOSTS 文件或 LMHOSTS 文件中添加适当的条目以纠正问题。

工具检测:


如果在两台计算机中的一台上安装了

SQL Server,则可以使用 DTCTester 实用程序检查这两台计算机之间是否支持事务处理。DTCTester实用程序使用 ODBC 检查 SQL Server 数据库是否支持事务处理。


如果两台计算机中都没有安装

SQL Server,则可以使用 DTCPing 检查这两台计算机之间是否支持事务处理。DTCPing 是在两台计算机中都没有安装 SQL Server 的情况下替代 DTCTester 实用程序的良好工具,使用时必须既在客户端计算机上运行,也在服务器计算机上运行。

四、 实现方式

1. Sql语句来使用事务

sqlserver2005/2008中支持,sqlserver 2000上不支持(try…… catch)

set xact_abort ON

begin try

begin tran

update [192.168.1.57].db_wps.dbo.wps_role set R_name = ‘57575757’ where R_ID =11;

update [192.168.1.52].db_wps.dbo.wps_role set R_name = ‘55255252’ where R_ID =11;

–RAISERROR (‘Error raised in TRY block.’,16,1);

commit tran

end try

begin catch

rollback tran

end catch


注意:注意直接用

server

名称

[192.168.1.52]夸服务器操作,需要调用如下存储过程:

exec sp_addlinkedserver   ‘192.168.1.52’, ‘ ‘, ‘SQLOLEDB ‘, ‘192.168.1.82’

exec sp_addlinkedsrvlogin  ‘192.168.1.52’, ‘false ‘,null, ‘sa’, ‘Aa123456’

2.NET—- SqlTransaction

或者

NET—- TransactionScope

添加引用System.Transactions.dll;

引用using System.Transactions;

SqlConnection  sqlConn = new SqlConnection( ConfigurationManager.ConnectionStrings[“ConnStr”].ConnectionString);

SqlTransaction  sqlTrans = null;

try {

sqlConn.Open();

sqlTrans = sqlConn.BeginTransaction();

//

事务开始


SqlCommand sqlComm = new SqlCommand(“”, sqlConn, sqlTrans);

sqlComm.CommandTimeout = 120;

sqlComm.CommandType = System.Data.CommandType.Text;

string insertSql = ” update [192.168.1.57]db_wps.dbo.wps_role set R_name = ‘57575757’ where R_ID =11″;

string updateSql = “update[192.168.1.52].db_wps.dbo.wps_role set R_name = ‘55255252’ where R_ID =11;”;

sqlComm.CommandText = insertSql; sqlComm.ExecuteNonQuery();

//

执行


insert sqlComm.CommandText = updateSql; sqlComm.ExecuteNonQuery();

//

执行

update //throw new Exception(“test exception.the transaction must rollback”);

sqlTrans.Commit();//

事务提交


} catch (Exception ex)

{


sqlTrans.Rollback();//

事务回滚


Console.WriteLine(ex.Message);

}

finally

{

if (sqlConn.State != System.Data.ConnectionState.Closed)

sqlConn.Close();

}

五、 DEMO

  1. 存储过程(192.168.1.64 DB_WPS )

WPS_DistributedTransaction

:批量

SQL语句,事务执行。

USE [DB_WPS]

GO

/****** Object:  StoredProcedure [dbo].[WPS_DistributedTransaction]    Script Date: 10/30/2014 16:01:32 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

— Batch submitted through debugger: SQLQuery10.sql|7|0|C:\Users\Administrator\AppData\Local\Temp\2\~vs4060.sql

— =============================================

— Author: <Author,,Name>

— Create date: <Create Date,,>

— Description: <Description,,>

— =============================================

ALTER PROCEDURE [dbo].[WPS_DistributedTransaction]

(

@Sql varchar(max),–sql

字符串组合,表名格式:


server.database.table

@split varchar(2), —

分隔符

@result int out  —

成功返回,失败返回

)

AS

BEGIN






SET NOCOUNT





ON


时,不返回计数(语句影响的行数)。

SET NOCOUNT ON;



如果执行


Transact-SQL


语句产生运行时错误,则整个事务将终止并回滚。

SET XACT_ABORT ON;



标记分割符位置

declare @location int



标记

起始

位置

declare @start int

–分隔符长度

declare @seed int

–执行的语句

declare @execsql varchar(1000)

set @Sql=ltrim(rtrim(@Sql))

set @start=1

set @seed=len(@split)

set @location=charindex(@split,@Sql)

begin try

begin tran

set @numere = LEN(@Sql)

while @location<>0 and @location < @numere

begin

set @location=charindex(@split,@Sql,@start)

if(@location = 0)

set @location = @numere +1

set @execsql = substring(@Sql,@start,@location-@start)

exec(@execsql)

set @start=@location+@seed

end

commit tran

set @result = 1

end try

begin catch

–此处写表,记录错误信息(省略)

rollback tran

set @result = 0

end catch

— Insert statements for procedure here

END


分析:如果记录详细的错误信息,由于存储过程不支持数组类型,建议传递

XML

参数。

2.NET—- TransactionScope

//

测试多数据库链接

public void TestSqlTransaction ()

{

string errorString = string.Empty;

try

{

using (TransactionScope scope = new TransactionScope())

{

//

更新


192.168.1.57


数据库的


DB_WPS



//using (SqlConnection conOne = new SqlConnection(“Data Source=192.168.1.57;database=DB_WPS;User ID=sa;Password=Aa123456”))

using (SqlConnection conOne = new SqlConnection(“Data Source=10.10.30.71;database=DB_WPS;User ID=sa;Password=Aa123456”))

{

conOne.Open();

SqlCommand command = new SqlCommand(“update db_wps.dbo.wps_role set R_name = ‘57575757’ where R_ID =11”, conOne);

int i = command.ExecuteNonQuery();

}

//

更新


192.168.1.52


数据库的


DB_WPS



using (SqlConnection conTwo = new SqlConnection(“Data Source=10.10.30.72;database=DB_WPS;User ID=sa;Password=Aa123456”))

{

conTwo.Open();

// SqlCommand command = new SqlCommand( “update db_wps.dbo.wps_role set R_name = ‘55255252’ where R_ID =11”, conTwo);

SqlCommand command = new SqlCommand(“update db_wps.dbo.wps_role set R_name = ‘000000000000000’ where R_ID =11”, conTwo);

int i = command.ExecuteNonQuery();

}

scope.Complete();  //

提交事物

}

}

catch (Exception ex)       //

发生异常后自动回滚

{

MessageBox.Show(ex.Message);

MessageBox.Show(errorString);

//throw;

}

}


优缺点分析:存储过程运行速度较快,

Net

机制事务运行速度稍慢。


存储过程难处理复杂的业务流程,存储过程管理较为麻烦

六、 总结


本文

DEMO只是基础测试,已调试成功,根据自己的业务需求不同,找到合适的方式和合理的代码结构。

  1. 能够通过调整业务结构、数据库结构避免分布式事务的,尽量不用分布式事务。

  2. 多数据库时才使用分布式事务,同一数据库,最好使用

    SqlTransaction。
  3. 分布式事务不支持跨域。

  4. 请注意

    MSDTC的设置和测试,详见第二章节。
  5. TransactionScope



    Net2.0以上的版本才支持。

转载于:https://www.cnblogs.com/guangang/articles/9267346.html