问题描述
我有一个 (enter code here)
mRef.child("users").addListenerForSingleValueEvent(object : ValueEventListener{
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot!!.getValue()!= null){
for (user in snapshot.children){
var sanMar=user.getValue(Users::class.java)
button4.setonClickListener {
textView13.text="${sanMar!!.user_id}"
textView14.text="${sanMar!!.adiSoyadi}"
textView15.text="${sanMar!!.phoneNumber}"
数据库,它严重依赖外部事件,例如管理员更改/添加某些字段或记录可能会触发其他表中整体字段结构的更改。
然而,问题在于,有时触发器函数更改的字段是主键字段。有一个表,它使用两个外键 id 作为主键,如下例所示:
postgresql
但是,在一个事务中(如果我可以这样称呼它,因为实际上它是一个 # | PK id1 | PK id2 | data |
0 | 1 | 1 | ab |
1 | 1 | 2 | cd |
2 | 1 | 3 | ef |
函数),结构可能会更改为:
plpgsql
您可能已经注意到,将第 0 条记录的第二个主键更改为 # | PK id1 | PK id2 | data |
0 | 1 | 3 | ab |
1 | 1 | 2 | cd |
2 | 1 | 1 | ef |
,将第 2 条记录的第二个主键更改为 3
,这与之前相反。
100% 确定函数生效后不会发生任何冲突,但我想知道,如何实现?
事实上,我可以使用合成主键作为 1
,但仍然需要包含 BIGSERIAL
这两个 ID,所以它不会成功,不幸的是。
解决方法
您可以将约束声明为可延迟的,例如主键:
CREATE TABLE elbat (id int,nmuloc int,PRIMARY KEY (id)
DEFERRABLE);
然后您可以在事务中使用 SET CONSTRAINTS
将可延迟约束设置为延迟。这意味着它们可以在事务期间暂时被违反,但必须在事务的 COMMIT
处得到满足。
假设我们的示例表中有一些数据:
INSERT INTO elbat (id,nmuloc)
VALUES (1,1),(2,2);
我们现在可以像这样切换 ID:
BEGIN TRANSACTION;
SET CONSTRAINTS ALL DEFERRED;
UPDATE elbat
SET id = 2
WHERE nmuloc = 1;
SELECT *
FROM elbat;
UPDATE elbat
SET id = 1
WHERE nmuloc = 2;
COMMIT;
即使 ID 在第一个 2
之后都是 UPDATE
,也没有错误。
db<>fiddle
更多信息可以在文档中找到,例如在 CREATE TABLE
(或 ALTER TABLE
)和 SET CONSTRAINTS
中。