最近遇到一个数据库存储过程多线程运算的问题,按照常规的做法,是写一个程序,在程序内多线程执行业务逻辑,这样做也不是不可以,但有以下不便:
1.开发周期长,在存储过程中实现的业务逻辑,在程序里实现一遍,要周期更长,维护更不便利。
2.原有的整体的业务逻辑是爱存储过程中实现,只有某一个业务节点需要多线程并行运算,如果该节点改为程序运行,业务节点间的衔接就没那么自然了。
实现的步骤:
1. c#创建数据库存储过程工程
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Text;
using System.Threading;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void AdjSelect(SqlInt32 iWeekID, SqlInt32 iObjType)
{
......................
int iCount = thparams.Length;
Queue thqueue = new Queue();
for (int i = 0; i < iCount; i++)
{
Thread th = new Thread(new ParameterizedThreadStart(objfunc));
th.Start((object)thparams[i]);
thqueue.Enqueue((object)th);
}
foreach (Thread th in thqueue)
{
th.Join();
}
}
编译后,部署DLL这时会出错,要修改dll工程属性的数据库标签中的安全级别,默认是“安全”,修改为“不安全”。
在安全的级别下,是不允许访问文件、注册表,不允许使用多线程等。。。
执行下列操作:
EXEC Sp_changedbowner 'xxxx',true
ALTER DATABASE DBXXXX SET TRUSTWORTHY on
注意:有可能出现错误信息:
sql assembly ***** XXX\Administrator 无法获取 权限信息,错误代码: 0x543,原因是把Administrator改名后,SQL Server识别不出来。
此外数据库属性 权限中,有用户是否使用不安全程序集的设定
在数据库的程序集下,添加c#扩展Dll到程序集列表中,修改权限集类型为“无限制”。
exec sp_configure 'clr enable', 1
go
reconfigure
go
exec dbo.xxxxxx --扩展存储过程
这里就能看到存储过程并行执行的效果了。如果机器资源足够,并行的效果还是很明显的,此方法适用于一个存储过程中,要执行几十个甚至上千个子任务,这种情况下,顺序执行的效率肯定是不如多线程执行。