How to avoid dirty read
I get two methods below: I would run both methods concurrently.
However, the "testRead" would always read the uncommitted results from "testInsert".
Anyway to avoid that? Thanks.
ClassMethod testInsert()
{
&sql(START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ WRITE)
&sql(insert into Test.Table(AttrA,AttrB,AttrC,AttrD) values(1,2,3,4))
hang 15
&sql(ROLLBACK)
}
ClassMethod testRead()
{
&sql(START TRANSACTION ISOLATION LEVEL READ COMMITTED)
&sql(select count(*) into :ans from Test.Table)
&sql(COMMIT)
w !,ans
}Comments
being suspicious on any * do you see the same behavior for
select count(AttrA) into :ans from Test.Table)
That seems to be just a part of the problem
do this change
START TRANSACTION %COMMITMODE EXPLICIT ISOLATION LEVEL READ COMMITTED, READ WRITE
docs:
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…
Found it:
Exceptions to READ COMMITTED 1 of some more
regardless of the specified ISOLATION LEVEL. Therefore, inserts and updates are in progress (and may subsequently be rolled back) are included in aggregate results. Deletes that are in progress (and may subsequently be rolled back) are
see:
http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…
As Robert C. said, the reason for this is because aggregate functions do not follow the rules of Read Committed mode. Moreover, the way to tell if you have values or not is to check SQLCODE, not the answer. For instance, even if you did:
&SQL(SELECT AttrA into :valA FROM Test."Table")
You could still find your value (1) in valA. Your next line should ALWAYS be checking SQLCODE. Without that check, you cannot be sure that the value in your variable is good.