Question

I have: Suppose I've got a table: Info with columns personId, laptopId and price.

Taks: Prevent inserting into Person table if prices summary of person's laptop is more than some constant.

Bad solution: Add a trigger

Problem: That solution isn't atomic. I mean between the triger checks the conditions and we proceed with INSERT another operation may be executed.

Question: How make it inthread safe way?

Was it helpful?

Solution

Assuming you create a materialized view log on Info, you can create a materialized view that does a fast refresh on commit

CREATE MATERIALIZED VIEW mv_check_totals
  REFRESH FAST 
  ON COMMIT
AS
SELECT personID,
       sum( price ) total_price
  FROM info
 GROUP BY personID
HAVING sum( price ) > <<some constant>>

You can then create a constraint on this materialized view that will be violated if any rows appear in the materialized view

ALTER TABLE mv_check_totals
  ADD CONSTRAINT constraint_name
       CHECK( personID IS NULL )

With this in place, the total price will be checked at commit time. You'll be allowed to INSERT as many rows as you'd like (after all, someone else could be deleting the existing rows in a separate session that will commit before you do). But you'll be stopped from committing the changes if they would violate your business rule. This is very much like the behavior you'd get with deferred constraints. But it does require a smarter application to recognize that a commit has failed and to alert the user to that fact rather than just reporting an error on a particular INSERT.

In this implementation, I put the constant in the materialized view definition so that the materialized view will be empty if the business rule is satisfied. That avoids the cost of storing the total. You might want to omit the HAVING clause and put the constant in your constraint, however. That would mean that you are storing extra data. But that makes it easier to change the constant in the future. And it materializes the total_price for each person if that is something that you are going to be presenting on reports.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top