我在本地的一个proc里有一些操作远程库的语句。并且对此想用事务,但发现超时。
proc代码如下:
/******数据传送处理进程 datatrans_proc*******/
IF EXISTS (SELECT * FROM sysobjects WHERE name='datatrans_proc')
DROP procedure datatrans_proc
go
Create procedure datatrans_proc
@transtime datetime,@sip varchar(100),@suser varchar(100),@suserpass varchar(100),
@logname varchar(100)
--,@iresult smallint =0 output
as
declare @outtime varchar(19),@iRows int
declare @linkstring varchar(1000)
declare @iCount int,@outno int,@localcode char(2),@headcode char(2)
declare @sql varchar(1000)
declare @stmp varchar(1000)
BEGIN TRAN--加上这句就超时
set @sql='Data Source='+@sip+';User ID='+@suser+';Password='+@suserpass
select @outtime=isnull(convert(char(19),outtime,120),'2008-01-01 00:00:00') from datatranstime where timeno=1
delete from syslogtemp--清空系统日志临时表
delete from cardconsumetemp--靖空卡消费流水临时表
delete from membertemp--清空会员临时表
insert syslogtemp select * from syslog where opertime>=@outtime--将本地系统日志最新数据放入临时表中
insert cardconsumetemp select * from cardconsume where consumdate>=@outtime--将本地消费最新流水数据放入临时表中
insert membertemp select * from member--将本地会员表放入临时表
select @outno=isnull(1,max(outno)+1) from dataoutlog--得到数据送表的最大编号
select @localcode=storecode from storecode where localflag=1--得到本店code
select @headcode=storecode from storecode where headflag=1--得到总店code
delete dataoutlog where outno=@outno and outtime=@transtime and logonname=@logname
insert dataoutlog values(@outno,@transtime,@localcode,@headcode,'传送中',@logname)
set @stmp='insert OPENDATASOURCE(''SQLOLEDB'','''+@Sql+''').database.dbo.datainlog values('+convert(varchar(10),@outno)+','+quotename(@transtime,'''')+','+quotename(@localcode,'''')+','+quotename(@headcode,'''')+','+quotename('传送中','''')+','+quotename(@logname,'''')+')'
exec(@stmp)
set @stmp='insert OPENDATASOURCE(''SQLOLEDB'','''+@Sql+''').database.dbo.syslogtemp select * from syslogtemp'
update dataoutlog set result='传送完毕' where outno=@outno and outtime=@transtime and logonname=@logname
update datatranstime set outtime=@transtime where timeno=1
COMMIT TRAN
go
proc代码如下:
/******数据传送处理进程 datatrans_proc*******/
IF EXISTS (SELECT * FROM sysobjects WHERE name='datatrans_proc')
DROP procedure datatrans_proc
go
Create procedure datatrans_proc
@transtime datetime,@sip varchar(100),@suser varchar(100),@suserpass varchar(100),
@logname varchar(100)
--,@iresult smallint =0 output
as
declare @outtime varchar(19),@iRows int
declare @linkstring varchar(1000)
declare @iCount int,@outno int,@localcode char(2),@headcode char(2)
declare @sql varchar(1000)
declare @stmp varchar(1000)
BEGIN TRAN--加上这句就超时
set @sql='Data Source='+@sip+';User ID='+@suser+';Password='+@suserpass
select @outtime=isnull(convert(char(19),outtime,120),'2008-01-01 00:00:00') from datatranstime where timeno=1
delete from syslogtemp--清空系统日志临时表
delete from cardconsumetemp--靖空卡消费流水临时表
delete from membertemp--清空会员临时表
insert syslogtemp select * from syslog where opertime>=@outtime--将本地系统日志最新数据放入临时表中
insert cardconsumetemp select * from cardconsume where consumdate>=@outtime--将本地消费最新流水数据放入临时表中
insert membertemp select * from member--将本地会员表放入临时表
select @outno=isnull(1,max(outno)+1) from dataoutlog--得到数据送表的最大编号
select @localcode=storecode from storecode where localflag=1--得到本店code
select @headcode=storecode from storecode where headflag=1--得到总店code
delete dataoutlog where outno=@outno and outtime=@transtime and logonname=@logname
insert dataoutlog values(@outno,@transtime,@localcode,@headcode,'传送中',@logname)
set @stmp='insert OPENDATASOURCE(''SQLOLEDB'','''+@Sql+''').database.dbo.datainlog values('+convert(varchar(10),@outno)+','+quotename(@transtime,'''')+','+quotename(@localcode,'''')+','+quotename(@headcode,'''')+','+quotename('传送中','''')+','+quotename(@logname,'''')+')'
exec(@stmp)
set @stmp='insert OPENDATASOURCE(''SQLOLEDB'','''+@Sql+''').database.dbo.syslogtemp select * from syslogtemp'
update dataoutlog set result='传送完毕' where outno=@outno and outtime=@transtime and logonname=@logname
update datatranstime set outtime=@transtime where timeno=1
COMMIT TRAN
go
exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '
exec sp_addlinkedsrvlogin 'ITSV ', 'false ',null, '用户名 ', '密码 ' --查询示例
select * from ITSV.数据库名.dbo.表名 --导入示例
select * into 表 from ITSV.数据库名.dbo.表名 --以后不再使用时删除链接服务器
exec sp_dropserver 'ITSV ', 'droplogins ' --连接远程/局域网数据(openrowset/openquery/opendatasource)
--1、openrowset --查询示例
select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名) --生成本地表
select * into 表 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名) --把本地表导入远程表
insert openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
select *from 本地表 --更新本地表
update b
set b.列A=a.列A
from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)as a inner join 本地表 b
on a.column1=b.column1 --openquery用法需要创建一个连接 --首先创建一个连接创建链接服务器
exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '
--查询
select *
FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')
--把本地表导入远程表
insert openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')
select * from 本地表
--更新本地表
update b
set b.列B=a.列B
FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ') as a
inner join 本地表 b on a.列A=b.列A --3、opendatasource/openrowset
SELECT *
FROM opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ' ).test.dbo.roy_ta
--把本地表导入远程表
insert opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ').数据库.dbo.表名
select * from 本地表
SQL没收。。
我的问题已经很清楚了:
在本地的一个proc里有一些操作远程库的语句。并且对此想用事务,但发现超时。
GOBEGIN TRAN
INSERT INTO t2 VALUES (4)
INSERT INTO t2 VALUES (5) /* Foreign key error */
INSERT INTO t2 VALUES (6)
COMMIT TRAN
GO
本例在本地和远程数据库上更新作者的姓。本地和远程数据库将同时提交或同时回滚本事务。
说明 除非正在运行 Microsoft® SQL Server™ 的计算机上当前装有 MS DTC,否则本例会产生错误信息。关于安装 MS DTC 的更多信息,请参见 Microsoft 分布式事务处理协调器文档。USE pubs
GO
BEGIN DISTRIBUTED TRANSACTION
UPDATE authors
SET au_lname = 'McDonald' WHERE au_id = '409-56-7008'
EXECUTE remote.pubs.dbo.changeauth_lname '409-56-7008','McDonald'
COMMIT TRAN
GO
不过如果是用set xact_abort的话,怎么判断是出错或不出错呢?
郁闷中啊。。
oprate local database {read modify tableX}step2:
oprate reomote database (read data from local database tableX}先看没有事务处理的情况:
step1执行后,你的tableX的更改已提交
再执行step2,这样没有问题.加入事处理:
step1执行完:
tableX 的修改没有提交.
step2执行时, tableX因为操作未提交, 表被锁定,反以它在等待 tableX的操作提交, 就限入了死等状态.我上面的 tableX 不是指一个表,而是指你本地上需要修改并且在远程操作时要读出的数据.
链接服务器的语句执行不在你的transaction范围内
BEGIN DISTRIBUTED TRANSACTION
.....
控制面板 -> 管理工具 -> 组件服务(component services)
打开这个窗口,你把第一个结点扩展开,一直到你看到“我的电脑(My Computer)”这个结点,
右键点击这个结点,里面有好多个页,选择“选项”那个页,
里面有个“事务超时”的设置,你会看到默认是60秒,改个大点的值试试。上面这个东西有点难找,我也找了半天。不是桌面上那个“我的电脑” :)