1、项目使用springmvc, spring, mybatis三个框架
2、在一个serverice中调用dao的方法,dao方法执行的是一个存储过程,该service方法在spring的事务中进行了如下配置<tx:method name="refreshMetaData" propagation="NEVER">,不使用事务管理。
3、数据库使用SQL Server 2008
现在service在执行refreshMetaData,出现了如下问题:
而在数据库中直接执行这个存储过程就不会出现任何错误信息,正常执行。存储过程中使用了SQL Server的链接服务器linkedserver。
存储过程代码如下:
1 CREATE PROC [dbo].[PRO_UPDATE_METADATA] 2 @metadataclassId int, 3 @parentmetadataclassId int, 4 @metadataTabName varchar(500), 5 @linkedServerName varchar(8000), 6 @planDBHost varchar(20), 7 @planDBName varchar(200), 8 @planDBUser varchar(200), 9 @planDBPWD varchar(200), 10 @planDBPort varchar(10), 11 @trans INT output 12 AS 13 DECLARE @remoteServer varchar(8000) =''; -- 远程服务器地址 14 DECLARE @TableName varchar(8000) =''; -- 代码表名称 15 DECLARE @TableNames varchar(8000) =''; -- 所有代码表名称组成的字符串 16 DECLARE @fieldName varchar(8000) ='';-- 元数据字段名称 17 DECLARE @fieldNames varchar(8000) ='';-- 元数据所有字段名称组成的字符串 18 DECLARE @fieldNamesWithTempTable varchar(8000) ='';-- 元数据所有字段名称组成的字符串 19 DECLARE @readFieldsSQL varchar(8000) = ''; -- 需要读取的字段 20 DECLARE @readFieldsSQL2 varchar(8000) = ''; -- 需要读取的字段 21 DECLARE @inserDataSql varchar(8000) ='';-- 存储元数据的SQL 22 23 DECLARE @result_flag int = 0; -- 出错标识,用户事物回滚提交 24 25 DECLARE @count int; 26 DECLARE fieldsCur CURSOR FOR select CODE_TABLE, FIELD_NAME from TBL_METADATA_CLASS_FIELD where 27 METADATA_ID=@metadataclassId or METADATA_ID=@parentmetadataclassId; -- 元数据字段 28 29 30 DECLARE @dataTblName varchar(200);-- 包含元数据属性的数据表名称 31 DECLARE @getCodeTableDataSQL varchar(8000);-- 获取代码表数据的SQL 32 DECLARE @getDataTableSQL varchar(8000); -- 获取数据表数据的SQL 33 DECLARE @unitFiles varchar(8000); -- 获取被审计单位信息 34 DECLARE @joinConditions varchar(8000); -- -数据表于代码表查询数据的条件 35 DECLARE @tableCursorSQL nvarchar(max); -- 动态创建游标SQL 36 37 BEGIN 38 39 /*创建链接服务器*/ 40 set @remoteServer = @planDBHost + ',' + @planDBPort 41 -- 判断链接服务器是否存在 42 IF EXISTS (SELECT 1 FROM MASTER..SYSSERVERS WHERE SRVNAME = @linkedServerName) 43 EXEC SP_DROPSERVER @linkedServerName,'DROPLOGINS' 44 -- 创建链接服务器 45 EXEC sp_addlinkedserver 46 @server=@linkedServerName, 47 @srvproduct='', 48 @provider='SQLOLEDB', 49 @datasrc=@remoteServer; 50 51 -- 登录链接服务器 52 EXEC sp_addlinkedsrvlogin @linkedServerName, 'false', NULL, @planDBUser, @planDBPWD 53 54 BEGIN TRANSACTION; 55 56 /*获取元数据字段信息*/ 57 set @count = 0; 58 set @joinConditions = ' 1=1 ' 59 Open fieldsCur; 60 fetch next from fieldsCur Into @TableName,@fieldName 61 While ( @@Fetch_Status=0 ) 62 begin 63 DECLARE @tableAlias varchar(30); 64 set @tableAlias = 'data_tab_' + CONVERT(varchar(2), @count); 65 set @readFieldsSQL = @readFieldsSQL + ', ' + '[' + @tableAlias + '].[' + @fieldName + '] as [' + @fieldName + ']'; 66 set @readFieldsSQL2 = @readFieldsSQL2 + ', ' + '[#dataTblName#].[' + @fieldName + '] as [' + @fieldName + ']'; 67 set @fieldNames = @fieldNames + ', ' + '[' + @fieldName + ']'; 68 set @fieldNamesWithTempTable = @fieldNamesWithTempTable + ', ' + '#codetabledata.[' + @fieldName + ']'; 69 set @TableNames = @TableNames + ',[' + @linkedServerName + '].[' + @planDBName + '].[dbo].' + '[' + @TableName + '] ' + @tableAlias; 70 set @joinConditions = @joinConditions + ' and [#dataTblName#].[' + @fieldName + ']=#codetabledata.[' + @fieldName + ']'; 71 set @count = @count + 1; 72 fetch next from fieldsCur Into @TableName,@fieldName; 73 end 74 Close fieldsCur; 75 Deallocate fieldsCur; 76 77 IF @@ERROR<>0 78 SET @result_flag=1; 79 80 -- 找出包含元数据分类属性的表 81 set @tableCursorSQL = 'DECLARE tablesCur CURSOR FOR select tblName from ( ' + 82 'select ' + 83 'sysobjects.name as tblName, ' + 84 'COUNT(*) as colCount ' + 85 'from ' + @linkedServerName + '.' + @planDBName + '.dbo.sysobjects ' + 86 'left join ' + 87 @linkedServerName + '.' + @planDBName + '.dbo.syscolumns ' + 88 'on sysobjects.id = syscolumns.id ' + 89 'where ' + 90 'sysobjects.xtype=''U'' ' + 91 'and syscolumns.name in ( ' + 92 'select FIELD_NAME from TBL_METADATA_CLASS_FIELD ' + 93 'where METADATA_ID=' + convert(varchar(20), @metadataclassId) + ' or METADATA_ID= ' + convert(varchar(20), @parentmetadataclassId) + 94 ') ' + 95 'group by sysobjects.name ' + 96 ') as cc where colCount >=' + convert(varchar(20), @count) + ' and tblName not like ''代码表_%'''; 97 98 exec sp_executesql @tableCursorSQL; 99 100 IF @@ERROR<>0 101 SET @result_flag=1 102 103 -- 清空数据信息表 104 exec ('truncate table ' + @metadataTabName); 105 open tablesCur; 106 fetch next from tablesCur Into @dataTblName 107 While ( @@Fetch_Status=0 ) 108 begin 109 -- 获取代码表数据 110 set @getCodeTableDataSQL = 'select distinct ' + SUBSTRING(@readFieldsSQL, 2, LEN(@readFieldsSQL)-1) + ' into #codetabledata from ' + SUBSTRING(@TableNames, 2, LEN(@TableNames)-1); 111 112 -- 基本单位信息 113 set @unitFiles = ',TBL_UNDERAUDITUNIT.[underauditunit] as [被采集单位信息], TBL_UNDERAUDITUNIT.[datadesc] as [数据信息描述], ' + 114 'TBL_UNDERAUDITUNIT.[othersoft] as [对方软件信息], TBL_UNDERAUDITUNIT.[remark] as [备注] '; 115 116 set @getDataTableSQL = 'select [col_id] as [DC_ID], [unit_id] ' + @unitFiles + REPLACE(@readFieldsSQL2, '#dataTblName#', @dataTblName) + ' into #metatableadata from #codetabledata ' + 117 'left join ' + 118 @linkedServerName + '.' + @planDBName + '.dbo.' + @dataTblName + ' ' + 119 'on ' + 120 REPLACE(@joinConditions, '#dataTblName#', @dataTblName) + ' ' + 121 'left join TBL_UNDERAUDITUNIT ' + 122 'on ' + 123 'TBL_UNDERAUDITUNIT.id = ' + @dataTblName + '.unit_id where col_id is not null'; 124 125 126 set @inserDataSql = ' insert into ' + @metadataTabName + '([DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ') select * from ( ' + 127 ' select [DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ' from #metatableadata ' + 128 ' except ' + 129 ' select [DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ' from ' + @metadataTabName + 130 ' ) as metatab '; 131 132 133 exec(@getCodeTableDataSQL + ';' + @getDataTableSQL + ';' + @inserDataSql + '; drop table #codetabledata; drop table #metatableadata;'); 134 135 136 fetch next from tablesCur Into @dataTblName 137 end 138 Close tablesCur; 139 Deallocate tablesCur; 140 141 IF @result_flag=1 142 BEGIN 143 ROLLBACK TRANSACTION 144 SET @trans=1 145 END 146 ELSE 147 BEGIN 148 COMMIT TRANSACTION 149 SET @trans =0 150 END 151 -- 退出登录 152 Exec sp_droplinkedsrvlogin @linkedServerName, null; 153 --删除链接服务器 154 Exec sp_dropserver @linkedServerName; 155 select @trans as trans 156 157 END