我们正试图以最简单的方式限制SIP服务器上的注册数量。更具体地说,我们决定限制users
表中的条目数。服务器正在运行PostgreSQL作为DBMS。
是否可以限制特定表格中的条目数量?例如,我们希望将行数限制为100,除非删除一些旧条目,否则我们不希望该表上有任何条目。
请告知。
答案 0 :(得分:3)
这是可能的,但这是解决这个问题的一种非常糟糕的方式。您必须创建一个触发器,在表上获取EXCLUSIVE
锁,然后在允许提交之前检查表上的count()
,或者,如果插入会添加太多行,则执行RAISE EXCEPTION
1}}中止事务。
实际上有两个触发器;执行BEFORE INSERT OR DELETE
和LOCK TABLE ... IN EXCLUSIVE MODE
触发器的AFTER INSERT
触发器,用于检查表的COUNT
并决定是否引发异常。简单的BEFORE
触发器是不够的,因为它无法判断INSERT
是否可能添加多行,因此多值插入或INSERT ... SELECT
可能会导致超出限制
其他想要更新表的会话必须等到执行INSERT
的事务完成。如果应用程序不是为此设计的,则很容易导致死锁。
当应用程序INSERT
进入会话表时,应用程序可能不会出现错误,因此它可能无法正常处理。它不太可能给用户一个整洁的“太多注册”错误。
我没有为此编写一个示例触发器,因为我认为这是一个绝对可怕的想法。如果要设置SIP服务器中可注册用户数的限制,请相应地配置SIP服务器。如果没有这样的配置选项,请修改它以添加一个或使用 具有的一个不同的SIP服务器。
答案 1 :(得分:1)
有点晚了,但我们遇到了同样的问题,所以我想分享我的解决方案。
我假设 user
表有一些父键或一些关系。
您可以通过锁定父记录并检查满足您条件的用户总数来在事务中完成此操作。如果它小于 limit
,那么您可以插入新用户。如果您尝试在另一笔交易中这样做,您将被锁定,直到第一个完成,或者您可以使用 SKIP LOCKED
获得空结果并完成交易。
代码:
BEGIN;
SELECT * FROM user_parent WHERE /* condition */ FOR UPDATE;
SELECT count(1) FROM "user" WHERE /* condition */;
// check count in your code
// if count <= limit; then continue; else ROLLBACK
// INSERT your users
COMMIT;
答案 2 :(得分:-1)
CONSTRAINT nomore_than_x_rows
CHECK( table_id < 101 );
鉴于id是serial
类型