{"Entry":{"collection":"sql","key":"listen","name":"LISTEN","aliases":["listen"],"metadata":{"aliases":["listen"],"changed_in":["6.5","9.0"],"changes":[{"from":"6.4","purpose_changed":true,"renamed":null,"sections":{"added":[],"changed":["description","usage"],"removed":[]},"status":"changed","synopsis":{"added":["LISTEN name"],"removed":["LISTEN notifyname"]},"to":"6.5"},{"from":"6.5","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","usage"],"removed":[]},"status":"changed","synopsis":null,"to":"7.0"},{"from":"7.0","purpose_changed":false,"renamed":{"from_file":"sql-listen.htm","to_file":"sql-listen.html"},"sections":{"added":[],"changed":[],"removed":[]},"status":"changed","synopsis":null,"to":"7.1"},{"from":"7.1","purpose_changed":true,"renamed":null,"sections":{"added":[],"changed":["description"],"removed":[]},"status":"changed","synopsis":null,"to":"7.2"},{"from":"7.2","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description"],"removed":[]},"status":"changed","synopsis":null,"to":"7.3"},{"from":"7.3","purpose_changed":false,"renamed":null,"sections":{"added":["parameters","examples","see_also"],"changed":["description","compatibility"],"removed":["usage"]},"status":"changed","synopsis":null,"to":"7.4"},{"from":"8.4","purpose_changed":false,"renamed":null,"sections":{"added":["notes"],"changed":["description","parameters"],"removed":[]},"status":"changed","synopsis":{"added":["LISTEN channel"],"removed":["LISTEN name"]},"to":"9.0"},{"from":"12","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","notes"],"removed":[]},"status":"changed","synopsis":null,"to":"13"},{"from":"16","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["see_also"],"removed":[]},"status":"changed","synopsis":null,"to":"17"}],"content_hash":"947d777f483aea25753d23fea02a1544cdf96387ae89d7bfe28e6a856b4bff99","editorial":{},"first_version":"6.4","group":"session","imported_at":"2026-09-30T17:43:39.420431+08:00","last_version":"20","name":"LISTEN","object":"","position":14001,"present_in":["6.4","6.5","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6","10","11","12","13","14","15","16","17","18","19","20"],"purpose":"listen for a notification","purpose_zh":"","related":["notify","unlisten"],"slug":"listen","source_rev":"a709ab85","synopsis":"LISTEN channel","verb":"LISTEN"}},"Definition":{"Collection":"sql","Key":"listen","SourceDatabase":"center","Version":"18","SourceTable":"sqlcmd","SourceKey":"listen","SourceRevision":"a709ab85","Facts":{"anchor":"SQL-LISTEN","file":"sql-listen.html","lang":"en","name":"LISTEN","purpose":"listen for a notification","purpose_zh":"","related":["notify","unlisten"],"sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e registers the current session as a listener on the notification channel named \u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e. If the current session is already registered as a listener for this notification channel, nothing is done.\u003c/p\u003e\u003cp\u003eWhenever the command \u003ccode class=\"command\"\u003eNOTIFY \u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e is invoked, either by this session or another one connected to the same database, all the sessions currently listening on that notification channel are notified, and each will in turn notify its connected client application.\u003c/p\u003e\u003cp\u003eA session can be unregistered for a given notification channel with the \u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e command. A session's listen registrations are automatically cleared when the session ends.\u003c/p\u003e\u003cp\u003eThe method a client application must use to detect notification events depends on which \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e application programming interface it uses. With the \u003cspan class=\"application\"\u003elibpq\u003c/span\u003e library, the application issues \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e as an ordinary SQL command, and then must periodically call the function \u003ccode class=\"function\"\u003ePQnotifies\u003c/code\u003e to find out whether any notification events have been received. Other interfaces such as \u003cspan class=\"application\"\u003elibpgtcl\u003c/span\u003e provide higher-level methods for handling notify events; indeed, with \u003cspan class=\"application\"\u003elibpgtcl\u003c/span\u003e the application programmer should not even issue \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e or \u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e directly. See the documentation for the interface you are using for more details.\u003c/p\u003e","key":"description","title":"Description"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eName of a notification channel (any identifier).\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"Parameters"},{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e takes effect at transaction commit. If \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e or \u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e is executed within a transaction that later rolls back, the set of notification channels being listened to is unchanged.\u003c/p\u003e\u003cp\u003eA transaction that has executed \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e cannot be prepared for two-phase commit.\u003c/p\u003e\u003cp\u003eThere is a race condition when first setting up a listening session: if concurrently-committing transactions are sending notify events, exactly which of those will the newly listening session receive? The answer is that the session will receive all events committed after an instant during the transaction's commit step. But that is slightly later than any database state that the transaction could have observed in queries. This leads to the following rule for using \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e: first execute (and commit!) that command, then in a new transaction inspect the database state as needed by the application logic, then rely on notifications to find out about subsequent changes to the database state. The first few received notifications might refer to updates already observed in the initial database inspection, but this is usually harmless.\u003c/p\u003e\u003cp\u003e\u003ca href=\"/docs/18/sql-notify.html\" title=\"NOTIFY\"\u003e\u003cspan class=\"refentrytitle\"\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e contains a more extensive discussion of the use of \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e and \u003ccode class=\"command\"\u003eNOTIFY\u003c/code\u003e.\u003c/p\u003e","key":"notes","title":"Notes"},{"html":"\u003cp\u003eConfigure and execute a listen/notify sequence from \u003cspan class=\"application\"\u003epsql\u003c/span\u003e:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eLISTEN virtual;\nNOTIFY virtual;\nAsynchronous notification \"virtual\" received from server process with PID 8448.\n\u003c/pre\u003e","key":"examples","title":"Examples"},{"html":"\u003cp\u003eThere is no \u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e statement in the SQL standard.\u003c/p\u003e","key":"compatibility","title":"Compatibility"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/notify/?v=18\" title=\"NOTIFY\"\u003e\u003cspan class=\"refentrytitle\"\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/unlisten/?v=18\" title=\"UNLISTEN\"\u003e\u003cspan class=\"refentrytitle\"\u003eUNLISTEN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/docs/18/runtime-config-resource.html#GUC-MAX-NOTIFY-QUEUE-PAGES\"\u003emax_notify_queue_pages\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"See Also"}],"sections_same_as":"","slug":"18","synopsis_html":"LISTEN \u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e","synopsis_text":"LISTEN channel"},"ManualEvidence":{},"MeasuredEvidence":{}},"Text":{"Collection":"sql","Key":"listen","SourceDatabase":"pgweb","Version":"18","Locale":"zh-Hans","Title":"LISTEN","Summary":"监听通知","BodyHTML":"\u003cpre\u003eLISTEN channel\u003c/pre\u003e\u003csection\u003e\u003ch2\u003e描述\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eLISTEN\u003c/code\u003e将当前会话注册为名为\u003cem\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e的通知通道的监听者。如果当前会话已经在该通知通道上注册为监听者，则不会执行任何操作。\u003c/p\u003e\u003cp\u003e每当命令\u003ccode\u003eNOTIFY \u003cem\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e被执行时，无论是由当前会话还是由另一个连接到同一数据库的会话执行，所有当前正在监听该通知通道的会话都会收到通知，而每个会话随后都会通知其所连接的客户端应用。\u003c/p\u003e\u003cp\u003e会话可以使用\u003ccode\u003eUNLISTEN\u003c/code\u003e命令取消在给定通知通道上的监听注册。会话结束时，其监听注册会被自动清除。\u003c/p\u003e\u003cp\u003e客户端应用必须采用何种方法来检测通知事件，取决于它所使用的 \u003cspan\u003ePostgreSQL\u003c/span\u003e应用程序编程接口。使用 \u003cspan\u003elibpq\u003c/span\u003e库时，应用程序将\u003ccode\u003eLISTEN\u003c/code\u003e 作为普通 SQL 命令发出，然后必须定期调用 \u003ccode\u003ePQnotifies\u003c/code\u003e函数，以判断是否已经收到任何通知事件。其他接口，例如\u003cspan\u003elibpgtcl\u003c/span\u003e，则提供了处理通知事件的更高层方法；事实上，在\u003cspan\u003elibpgtcl\u003c/span\u003e中，应用程序员甚至不应直接发出\u003ccode\u003eLISTEN\u003c/code\u003e或\u003ccode\u003eUNLISTEN\u003c/code\u003e。详见所使用接口的相关文档。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e参数\u003c/h2\u003e\u003cdiv\u003e\u003cdl\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e通知通道的名称（任意标识符）。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e注解\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eLISTEN\u003c/code\u003e会在事务提交时生效。如果在随后被回滚的事务中执行了\u003ccode\u003eLISTEN\u003c/code\u003e或 \u003ccode\u003eUNLISTEN\u003c/code\u003e，则被监听的通知通道集合不会发生变化。\u003c/p\u003e\u003cp\u003e执行过\u003ccode\u003eLISTEN\u003c/code\u003e的事务不能进入两阶段提交的预备状态。\u003c/p\u003e\u003cp\u003e第一次建立监听会话时存在一个竞争条件：如果并发提交的事务正在发送通知事件，那么新开始监听的会话究竟会收到其中哪些事件？答案是，该会话会收到那些在其事务提交步骤中的某个时刻之后提交的所有事件。但这个时刻会略晚于该事务通过查询所能观察到的任何数据库状态。因此，使用\u003ccode\u003eLISTEN\u003c/code\u003e 时应遵循如下规则：先执行该命令并提交，然后在一个新事务中按照应用逻辑的需要检查数据库状态，之后再依靠通知来获知数据库状态的后续变化。最初收到的几个通知，可能对应于初次检查数据库时已经观察到的更新，但这通常无害。\u003c/p\u003e\u003cp\u003e\u003ca href=\"/docs/18/sql-notify.html\" title=\"NOTIFY\" rel=\"nofollow\"\u003e\u003cspan\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e中对\u003ccode\u003eLISTEN\u003c/code\u003e和\u003ccode\u003eNOTIFY\u003c/code\u003e的使用有更详细的讨论。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e示例\u003c/h2\u003e\u003cp\u003e在\u003cspan\u003epsql\u003c/span\u003e中配置并执行一组 listen/notify 操作：\u003c/p\u003e\u003cpre\u003eLISTEN virtual;\nNOTIFY virtual;\nAsynchronous notification \u0026#34;virtual\u0026#34; received from server process with PID 8448.\n\u003c/pre\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e兼容性\u003c/h2\u003e\u003cp\u003eSQL 标准中没有\u003ccode\u003eLISTEN\u003c/code\u003e语句。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e另见\u003c/h2\u003e\u003cspan\u003e\u003ca href=\"/wiki/sql/notify/?v=18\" title=\"NOTIFY\" rel=\"nofollow\"\u003e\u003cspan\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/unlisten/?v=18\" title=\"UNLISTEN\" rel=\"nofollow\"\u003e\u003cspan\u003eUNLISTEN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/docs/18/runtime-config-resource.html#GUC-MAX-NOTIFY-QUEUE-PAGES\" rel=\"nofollow\"\u003emax_notify_queue_pages\u003c/a\u003e\u003c/span\u003e\u003c/section\u003e","SourceRevision":"1b5ca64c","ContentHash":"4c570b5a3352d518f8367822d35879b1c88293d976d6e6ef8378dbee196340e3","Payload":{"purpose_zh":"监听通知","sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e将当前会话注册为名为\u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e的通知通道的监听者。如果当前会话已经在该通知通道上注册为监听者，则不会执行任何操作。\u003c/p\u003e\u003cp\u003e每当命令\u003ccode class=\"command\"\u003eNOTIFY \u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e被执行时，无论是由当前会话还是由另一个连接到同一数据库的会话执行，所有当前正在监听该通知通道的会话都会收到通知，而每个会话随后都会通知其所连接的客户端应用。\u003c/p\u003e\u003cp\u003e会话可以使用\u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e命令取消在给定通知通道上的监听注册。会话结束时，其监听注册会被自动清除。\u003c/p\u003e\u003cp\u003e客户端应用必须采用何种方法来检测通知事件，取决于它所使用的 \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e应用程序编程接口。使用 \u003cspan class=\"application\"\u003elibpq\u003c/span\u003e库时，应用程序将\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e 作为普通 SQL 命令发出，然后必须定期调用 \u003ccode class=\"function\"\u003ePQnotifies\u003c/code\u003e函数，以判断是否已经收到任何通知事件。其他接口，例如\u003cspan class=\"application\"\u003elibpgtcl\u003c/span\u003e，则提供了处理通知事件的更高层方法；事实上，在\u003cspan class=\"application\"\u003elibpgtcl\u003c/span\u003e中，应用程序员甚至不应直接发出\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e或\u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e。详见所使用接口的相关文档。\u003c/p\u003e","key":"description","title":"描述"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e通知通道的名称（任意标识符）。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"参数"},{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e会在事务提交时生效。如果在随后被回滚的事务中执行了\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e或 \u003ccode class=\"command\"\u003eUNLISTEN\u003c/code\u003e，则被监听的通知通道集合不会发生变化。\u003c/p\u003e\u003cp\u003e执行过\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e的事务不能进入两阶段提交的预备状态。\u003c/p\u003e\u003cp\u003e第一次建立监听会话时存在一个竞争条件：如果并发提交的事务正在发送通知事件，那么新开始监听的会话究竟会收到其中哪些事件？答案是，该会话会收到那些在其事务提交步骤中的某个时刻之后提交的所有事件。但这个时刻会略晚于该事务通过查询所能观察到的任何数据库状态。因此，使用\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e 时应遵循如下规则：先执行该命令并提交，然后在一个新事务中按照应用逻辑的需要检查数据库状态，之后再依靠通知来获知数据库状态的后续变化。最初收到的几个通知，可能对应于初次检查数据库时已经观察到的更新，但这通常无害。\u003c/p\u003e\u003cp\u003e\u003ca href=\"/docs/18/sql-notify.html\" title=\"NOTIFY\"\u003e\u003cspan class=\"refentrytitle\"\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e中对\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e和\u003ccode class=\"command\"\u003eNOTIFY\u003c/code\u003e的使用有更详细的讨论。\u003c/p\u003e","key":"notes","title":"注解"},{"html":"\u003cp\u003e在\u003cspan class=\"application\"\u003epsql\u003c/span\u003e中配置并执行一组 listen/notify 操作：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eLISTEN virtual;\nNOTIFY virtual;\nAsynchronous notification \"virtual\" received from server process with PID 8448.\n\u003c/pre\u003e","key":"examples","title":"示例"},{"html":"\u003cp\u003eSQL 标准中没有\u003ccode class=\"command\"\u003eLISTEN\u003c/code\u003e语句。\u003c/p\u003e","key":"compatibility","title":"兼容性"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/wiki/sql/notify/?v=18\" title=\"NOTIFY\"\u003e\u003cspan class=\"refentrytitle\"\u003eNOTIFY\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/wiki/sql/unlisten/?v=18\" title=\"UNLISTEN\"\u003e\u003cspan class=\"refentrytitle\"\u003eUNLISTEN\u003c/span\u003e\u003c/a\u003e, \u003ca href=\"/docs/18/runtime-config-resource.html#GUC-MAX-NOTIFY-QUEUE-PAGES\"\u003emax_notify_queue_pages\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"另见"}],"sections_same_as":"","synopsis_html":"LISTEN \u003cem class=\"replaceable\"\u003e\u003ccode\u003echannel\u003c/code\u003e\u003c/em\u003e","synopsis_text":"LISTEN channel"}},"RequestedLocale":"zh-Hans","Fallback":false,"Versions":["10","11","12","13","14","15","16","17","18","19","20","6.4","6.5","7.0","7.1","7.2","7.3","7.4","8.0","8.1","8.2","8.3","8.4","9.0","9.1","9.2","9.3","9.4","9.5","9.6"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
