๐ฏ Goals
- ํธ๋ฆฌ๊ฑฐ , ํธ๋์ญ์ ๋ด์์ ์ธ์ ์คํ๋ ๊น?
3๊ฐ์ง ํ์ ์ ํธ๋ฆฌ๊ฑฐ
- BEFORE
- โ AFTER (Only handle this in this post)
- INSTEAD OF
๊ฐ ํธ๋ฆฌ๊ฑฐ ํ์ ์ ๋ฐ๋ผ Default Behavior ๊ฐ ๋ค๋ฅด๋ฏ๋ก ๊ผญ ๊ณต์๋ฌธ์๋ฅผ ์ฐธ์กฐํ๊ธธ ๋ฐ๋๋ค. ์ด ๊ธ์์ `AFTER` ํธ๋ฆฌ๊ฑฐ๋ง ๋ค๋ฃฌ๋ค.
์๋ SQL๋ฌธ์ ๋ณด๊ณ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์์ํด๋ณด์.
Each statement? vs After all transaction `COMMIT()`?
๋น์ฐํ ๋๋ ํ์๋ก ์๊ณ ์์๋ค, ํธ๋์ญ์ ์ ๋ชจ๋ Statement ๊ฐ ๋๋ ํ์ `COMMIT()` ๋ ์์ ์ ํธ๋ฆฌ๊ฑฐ๊ฐ ๋ฐ๋ํ ์ค ์์๋ค.
์์ํ ๋ก๊ทธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
โ ํ๋ ธ๋ค, ๊ฐ ๋ฌธ์ฅ๋ง๋ค ๊ณง๋ฐ๋ก ํธ๋ฆฌ๊ฑฐ๊ฐ ์คํ๋๋ค.
๊ณต์ ๋ฌธ์ ํ์ณ๋ณด๊ธฐ
Row-level `BEFORE` triggers fire immediately before a particular row is operated on,
while row-level `AFTER` triggers fire at the end of the statement (but before any statement-level
`AFTER` triggers).
The execution of an `AFTER` trigger can be deferred to the end of the transaction, rather than the end of the statement, if it was defined as a constraint trigger.
In all cases, a trigger is executed as part of the same transaction as the statement that triggered it, so if either the statement or the trigger causes an error, the effects of both will be rolled back.
๐ ํธ๋ฆฌ๊ฑฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก Statement ๊ฐ ๋๋๋ ์์ ์ ์คํ๋์ง๋ง, `Constraint` ๋ฅผ ๊ฑธ๋ฉด, AFTER ํธ๋ฆฌ๊ฑฐ์ ์คํ ์์ ์ ํธ๋์ญ์ ์ข ๋ฃ์๋ก ๋ฏธ๋ฃฐ ์ ์๋ค.
Constraint Trigger ๋ก ์ง์ฐ ์คํํ๊ธฐ
๊ฒฐ๋ก ์ ๋งค์ฐ ๊ฐ๋จํ๋ค, ํธ๋ฆฌ๊ฑฐ ์์ฑ์ `CONSTRAINT` ํค์๋์ `INITALLY DEFERRED` ์ต์ ๋ง ๋ถ์ฌ์ฃผ๋ฉด ๋๋ค.
โ ๏ธ CONSTRAINT TRIGGER ๋ ์ค๋ก์ง `AFETR` ํธ๋ฆฌ๊ฑฐ์ FOR EACH ROW ๋ ๋ฒจ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
์ด์ ๊ด๋ จ๋ ๋๊ฐ์ง ์ต์ ์ ๋ชจ๋ ์๊ณ ์์ด์ผ ์ ์ ํ ์ฉ๋๋ก ์ธ ์ ์๋ค.
[DEFERRABLE]
(์ค๋ต..)
A constraint that is not deferrable will be checked immediately after every command.
Checking of constraints that are deferrable can be postponed until the end of the transaction (using the SET CONSTRAINTS command). NOT DEFERRABLE is the default. Currently, only UNIQUE, PRIMARY KEY, EXCLUDE, and REFERENCES (foreign key) constraints accept this clause. NOT NULL and CHECK constraints are not deferrable.
[INITIALLY DEFERRED]
If a constraint is deferrable, this clause specifies the default time to check the constraint. If the constraint is
INITIALLY IMMEDIATE, it is checked after each statement. This is the default.
If the constraint is INITIALLY DEFERRED, it is checked only at the end of the transaction. The constraint check time can be altered with the SET CONSTRAINTS command.
์๋ฌธ ๊ทธ๋๋ก ์ง์ญํ์ ๋๋ ์ฉ๋์ ๋์ ๋ฐฉ์์ ์ฐจ์ด๊ฐ ์๋ฆฌ์กํ๋ค.
โ ๏ธ DEFERRABLE ์ต์ ๊ณผ
INITIALLY DEFERRED ์ต์ ์ ๋ค๋ฅด๋ค.
DEFERRABLE
๐๐ป Unique, PK, EXCLUDE, FK ์ ์ฝ์กฐ๊ฑด ๊ฒ์ฌ๋ฅผ ํธ๋์ญ์ ์ข ๋ฃ ์์ ๊น์ง ์ง์ฐ์ํจ๋ค.
(Default: NOT DEFERRABLE, (SQL ๋ฌธ์ฅ ๋จ์๋ก ์ ์ฝ์กฐ๊ฑด ๊ฒ์ฆ))
INITIALLY DEFERRED
๐๐ป ๋ชจ๋ ๋ฌธ์ฅ์ ์ ์ฝ ์กฐ๊ฑด ๊ฒ์ฆ์ ํธ๋์ญ์ ์ข ๋ฃ ์์ ๊น์ง ์ง์ฐ์ํจ๋ค.
(Default: INITIALLY IMMEDIATE)
โ ๏ธ ์ ์์ ์์ `DEFFERABLE' ๋ง ์ค์ ํ๋ฉด ์ด์ ์์ ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป๋๋ค.
(SQL 1๋ฒ -> ํธ๋ฆฌ๊ฑฐ ๋ฐ๋-> SQL 2๋ฒ -> ํธ๋ฆฌ๊ฑฐ ๋ฐ๋)
๐ค ์ด๊ฒ ๋ญ ๋ป์ด์ง? (์ถํ ๋ถ์)
In all cases, a trigger is executed as part of the same transaction as the statement that triggered it, so if either the statement or the trigger causes an error, the effects of both will be rolled back.
๋ฌธ์ฅ์ด ํธ๋ฆฌ๊ฑฐ ์ํด์ผ๋ก์จ, ํธ๋ฆฌ๊ฑฐ๋ ํธ๋์ญ์ ์ ์ผ๋ถ๋ก ์คํ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ฌธ์ฅ์ด๋ ํธ๋ฆฌ๊ฑฐ๊ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด, ์์ชฝ๋ค ๋กค๋ฐฑ๋๋ค.
์ง์ญ์ ์ด๋ฌํ๋ฐ ์๋ฟ์ง ์๋๋ค. ์ ํํ ์์๊ฐ ํ์ํ๋ค.
๐ Reference
'DataBase > PostgreSQL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[PostgreSQL] Use `identity` instead of `serial` (0) | 2022.06.16 |
---|---|
[PostgreSQL] CHECK Constraint (0) | 2022.05.04 |
[PostgreSQL] Transaction + Pool ์ฌ์ฉ์ ์ฃผ์ (0) | 2022.04.04 |
[PostgreSQL] Function (feat. trigger) (0) | 2022.03.29 |
[PostgreSQL] Notify (0) | 2022.03.25 |