异步调用存储

 起源

  因为项目中,需要用到存储过程进行大量的计算,存储过程执行的速度让人感觉揪心,不能说让客户在页面上待个几分钟吧,因此就想,有没有一种方法,可以做到客户发出请求,然后数据库在后台执行任务,于是.......

具体方法

  经过百度知道,作业可以在后台自动执行一段存储过程,所以,通过动态生成作业,然后作业再调用存储过程就好了,动态生成作业就需要到存储过程的帮助,通过设置好一些参数后,生成一个临时作业,然后设置作业立即执行就可以了,下面是生成动态作业的代码,这个存储过程是在网上找的,但是自己也有改过一些代码,满足我们自己的项目需求

 1 set ANSI_NULLS ON
 2 set QUOTED_IDENTIFIER ON
 3 GO
 4 /******************************************************************************
 5 * 在SQL SERVER 中创建用于执行异步调用的临时Job
 6 * @EXECSQL: 填写要执行的存储过程的名称,或者是sql语句
 7 ******************************************************************************/
 8 ALTER Procedure [dbo].[AsyRunPro]
 9 @EXECSQL nvarchar(4000)='EXEC dbo.BatchRatingAsy ',
10 @job nvarchar(50)='JL_AsynchronousInvoking',
11 @servern nvarchar(50)=N'(local)' ,
12 @dbname nvarchar(50)=''--下面会通过db_name()函数获取
13 AS
14 
15 BEGIN TRANSACTION
16 DECLARE @JobID BINARY(16)
17 DECLARE @ReturnCode INT
18 SELECT @ReturnCode = 0
19 
20 BEGIN
21 SET @dbname=CONVERT(NVARCHAR(50),db_name())
22 --SELECT @dbname 
23 -- Add the job
24 EXECUTE @ReturnCode = msdb.dbo.sp_add_job @job_id = @JobID OUTPUT ,
25 @job_name = @job,
26 @owner_login_name = N'',
27 @description = N'AsynchronousInvokingRating', -- the description of the job
28 @category_name = N'[Uncategorized (Local)]', 
29 @enabled = 1,
30 @notify_level_email = 0,
31 @notify_level_page = 0,
32 @notify_level_netsend = 0,
33 @notify_level_eventlog = 0,
34 @delete_level= 3
35 
36 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
37 
38 -- Add the job steps
39 EXECUTE @ReturnCode = msdb.dbo.sp_add_jobstep @job_id = @JobID,
40 @step_id = 1,
41 @step_name = N'step1',
42 @command = @EXECSQL, -- sql batch
43 @database_name = @dbname, --作业所操作的数据库的名字
44 @server = N'',
45 @database_user_name = N'',
46 @subsystem = N'TSQL',
47 @cmdexec_success_code = 0,
48 @flags = 0,
49 @retry_attempts = 0, --只是执行一次
50 @retry_interval = 0,
51 @output_file_name = N'',
52 @on_success_step_id = 0,
53 @on_success_action = 1, -- 成功则删除
54 @on_fail_step_id = 0,
55 @on_fail_action = 2 -- on fail abort
56 --select @JobID
57 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
58 
59 --set the star step id of the job
60 EXECUTE @ReturnCode = msdb.dbo.sp_update_job @job_id = @JobID,
61 @start_step_id = 1
62 
63 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
64 
65 -- Add the Target Servers
66 EXECUTE @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @JobID,
67 @server_name = @servern--传入的服务器名称
68 
69 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
70 
71 END
72 
73 COMMIT TRANSACTION
74 GOTO EndSave
75 
76 QuitWithRollback:
77 IF (@@TRANCOUNT > 0) BEGIN
78 ROLLBACK TRANSACTION
79 RETURN 1
80 END
81 EndSave:
82 
83 --立刻开启作业
84 EXEC @ReturnCode = msdb.dbo.sp_start_job @job_id = @JobID
85 
86 --返回响应调用者
87 RETURN @ReturnCode

上面写出一些主要的参数的注释,对于具体创建作业可以到 http://msdn.microsoft.com/zh-cn/library/ms187880.aspx 去了解,这里就不再继续说了

注意事项

其中要注意的是,作业的执行需要Agent服务的支持所以在SQL SERVER Configuration Manager 开启 SQL SERVER AGENT 服务,如果项目是一直需要用到的话,最好设置为自动开启,因为如果因为Agent服务未能成功开启的话,作业就不会被自动删除,那就意味着,下次如果是创建同名的作业的话,就无法创建成功!所以,最好要考虑万一作业未能删除,就要怎么办,而我自己的作法是不创建重名的作业~~~

总结

当然异步调用有好也有不好,好的就是让客户感觉到"速度",但是真正来说,存储过程并未能完全执行完毕,也不知道何时执行完毕,当然也可以再做一个功能去检查存储过程何时执行完毕~~

posted @ 2012-08-17 20:44  jeanlyn  阅读(1524)  评论(0)    收藏  举报