- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想将数据从数据库推送到应用程序而不是应用程序拉取数据。我已经安装了 ms sql server 和 apache tomcat 服务器。我在 apache tomcat 中有我的应用程序,在这里我连接到数据库。现在我希望数据库在数据更新时发送数据。但我所知道的是从数据库中获取数据并不是一个好主意,因为应用程序需要监视数据库的更新数据将导致每 5 秒触发一次查询,这也不是很有效。
我用谷歌搜索得到了一些答案,它们是查询通知 here ,sql server Agent Job 自动调度任务。如果您有任何其他建议,请发布。
最佳答案
肯定有几种可能性可以做到这一点:
您可以在此讨论中阅读一些关于它们的信息: Serial numbers, created and modified in SQL Server .
我个人更喜欢查询通知而不是其他方法,因为它已经支持各种情况(例如同步/异步通信),而且您不必重新发明轮子。并且在您的案例中是 Microsoft 推荐的。
轮询是您提到的另一种方法。它更像是一种传统方法,可能会有一些相关的性能损失,但如果你足够小心,你不应该担心它们。例如,如果您的应用程序中已经内置了身份验证,则可以在 Users
表中创建另一列,如果与该用户相关的任何更改都会设置该列。然后,您的应用程序中可能只有一个线程每秒对该表执行一次查询(即使使用 NOLOCK 进行脏读在这里也不成问题)并维护一些内存结构(例如线程安全字典)那就是说哪个客户应该被推送。另一个线程轮询您的字典,当它为客户端找到某些内容时,执行数据库查询以提取数据并将其发送给客户端。这看起来像是很多不必要的工作,但最后你得到了两个独立的 worker ,这在一定程度上有助于分离关注点;第一个只是执行“轻量级”数据库轮询的告密者;第二个提取真实数据并执行服务器推送。您甚至可以优化 push-worker,使其在运行时检查是否有多个客户端需要一些数据,然后为所有需要它的人执行选择。您可能希望第二个 worker 的运行频率低于第一个。
编辑
如果您希望使用非 .NET 技术来实现相同的功能,则必须更深入地了解 SQL Server Service Broker。 Query Notification 是在 SQL Server Service Broker 之上构建在 .NET 中的简化层,您必须自己构建该层的至少一部分。这包括在另一端使用 SEND 和 RECEIVE 创建队列、消息类型、服务和存储过程。您必须自己处理对话/对话。 SB 实际上是一个调整为在 RDBMS 环境中工作的异步消息世界,因此您会看到一些新的 TSQL 表达式。但是,MSDN 可以提供帮助:
这也有帮助:Externally activate non-.NET application from Service Broker
关于如何编写代码的示例:
-- First you have to enable SB for your database
USE master
ALTER DATABASE Playground
SET ENABLE_BROKER
GO
USE Playground
GO
-- Then create a message type; usually it will be XML
-- because it's very easy to serialize/deserialize it
CREATE MESSAGE TYPE [//Playground/YourMessageType]
VALIDATION = WELL_FORMED_XML
GO
-- Then create a contract to have a rule for communication
-- Specifies who sends which message type
CREATE CONTRACT [//Playground/YourContract] (
[//Playground/YourMessageType] SENT BY ANY)
GO
--Creates queues, one for initiator (1) and one for target (2)
CREATE QUEUE MyQueue1
GO
CREATE QUEUE MyQueue2
GO
-- Finally, configure services that 'consume' queues
CREATE SERVICE [//Playground/YourService1]
ON QUEUE MyQueue1 ([//Playground/YourContract])
GO
CREATE SERVICE [//Playground/YourService2]
ON QUEUE MyQueue2 ([//Playground/YourContract])
GO
-- Now you can send a message from service to service using contract
DECLARE
@dHandle uniqueidentifier,
@Msg nvarchar(max)
BEGIN DIALOG @dHandle
FROM SERVICE [//Playground/YourService1]
TO SERVICE '//Playground/YourService2'
ON CONTRACT [//Playground/YourContract]
WITH ENCRYPTION = OFF
SELECT @Msg = (
SELECT TOP 3 *
FROM Table1
FOR XML PATH('row'), ROOT('Table1'))
;SEND ON CONVERSATION @dHandle
MESSAGE TYPE [//Playground/YourMessageType] (@Msg)
PRINT @Msg
GO
-- To get the message on the other end, use RECEIVE
-- Execute this in another query window
DECLARE @dHandle uniqueidentifier
DECLARE @MsgType nvarchar(128)
DECLARE @Msg nvarchar(max)
;RECEIVE TOP(1)
@dHandle = conversation_handle,
@Msg = message_body,
@MsgType = message_type_name
FROM MyQueue2
SELECT @MsgType
SELECT @Msg
END CONVERSATION @dHandle
GO
关于sql-server - 如何将数据从数据库推送到应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17207550/
我是一名优秀的程序员,十分优秀!