Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!husc6!mit-eddie!ll-xn!ames!lll-lcc!lll-tis!ptsfa!rtech!jeff From: jeff@rtech.UUCP (Jeff Lichtman) Newsgroups: comp.databases Subject: Re: BIG, BIG fun w/Informix cursors Message-ID: <1091@rtech.UUCP> Date: Sat, 25-Jul-87 03:45:55 EDT Article-I.D.: rtech.1091 Posted: Sat Jul 25 03:45:55 1987 Date-Received: Sun, 26-Jul-87 00:36:26 EDT References: <230@paisano.UUCP> Organization: Relational Technology Inc. Alameda, CA 94501 Lines: 145 From article <230@paisano.UUCP>, by demasi@paisano.UUCP (Michael C. De Masi): > In article <1076@rtech.UUCP>, jeff@rtech.UUCP (Jeff Lichtman) writes: >> From article <229@paisano.UUCP>, by demasi@paisano.UUCP (Michael C. De Masi): >> >> Now that we've established why the DBMS releases locks at commit or >> rollback time, let's consider why cursors must be closed at commit >> time... > > Now granted, I probably don't have the level of understanding about > database theory that you do, but what about purely readonly queries that > do not cause any locking? Usually, a DBMS will get and hold shared locks (also called "read locks") until end transaction time. What most DBMS's guarantee by default is serializability, also called "level-three consistency". A set of concurrent transactions is serializable if there is some way of doing all of the transactions non-concurrently and getting the same result. That is, if you can untangle all of the interleaved operations in your concurrent transactions, and then can find some way of laying your transactions end-to-end in such a way that it would produce the same result, the transactions are called serializable. This can be a hard concept to absorb at first, so I'll put it a different way: the job of concurrency control in a DBMS is to ensure that users get a consistent view of the data. For a read-only transaction, this requires two things: that the transaction not be able to see other users' uncommitted updates, and that reading the same record more than once within the same transaction will yield the same values every time. This requires getting and holding read locks until end transaction time, even if it is a read-only transaction. Suppose, for instance, that you have database containing account information. There are two programs running: one is using a read-only transaction to add up all the accounts to make sure things balance. Another is running transactions to transfer funds between accounts. If the read-only transaction didn't get read locks, it would be possible for it to see some half-done updates from the transfer transactions, and the accounts wouldn't balance. (Note that there are other methods of concurrency control besides locking. I won't discuss any of the other methods here.) Now suppose that a similar situation exists, except the read-only transaction has two parts: first, it tallies all accounts with a positive balance, and then it tallies all accounts with a negative balance. Again, assume that there is another set of transactions going on at the same time that transfer funds between accounts. If the read-only transaction doesn't hold its locks until end transaction time, it's possible that an update to an account will cause it to be seen as a positive-balance account on the first pass, and a negative-balance account on the second pass. Thus, in order to guarantee the user a consistent view of the data, a DBMS must get and hold locks, even in a read-only transaction. This is true in the general case. However, if the DBMS knew enough about the user's application, it might be able to figure out when locks were no longer needed and release them earlier. For example, a transaction that does nothing but read from a single table, and never re-reads anything, doesn't need to hold its read locks until the end of the transaction; it only needs to hold its locks on each record, page, or whatever, until the application is done with the it. Please note, however, that a DBMS has no way of knowing whether this will be true, because it doesn't have the brains to study the application to see what it's doing. The programmer does have the brains, however. Some DBMS's allow the user to control locking in various ways; Ingres, for instance, allows the user to tell it not to use locks when reading. But all relational DBMS's that I know of use level-three consistency as the default. That is, some DBMS's allow the user to risk seeing inconsistent views of the data, but it must be done by the explicit action of the user. > Granted, commiting an update does change the > nature of a given table, but can't that happen anyway? That is, if I > do a readonly query of a group of database records, and one gets changed > by another process or user before I advance to that record, won't I get > incorrect or no longer existing data, or is there some functionality > that takes care of this of which I'm not aware? If so, couldn't this > same fuctioanlity be used to keep readonly cursors open under the > circumstances I've described? This could be a problem if read-only transactions didn't get and hold locks. But they do, and a consequence is that even read-only transactions won't see another transaction's incomplete updates. It is possible for one transaction to see another's *comitted* updates, but that's perfectly OK. >> It seems that Mr. De Masi got into this mess by trying to use "commit >> work" and "rollback work" to guarantee the success or failure of >> individual database statements... > > No, not unless you consider that one database 'transaction' from the > viewpoint of the user, may actually consist of any number of individual > database statements, any one of which is subject to failure... It sounded to me like the application was written something like this: database statement; if (success) commit work; else rollback work; database statement; if (success) commit work; else rollback work; database statement; if (success) commit work; else rollback work; ... commit work; When it should be written like this: database statement; if (failure) rollback work; database statement; if (failure) rollback work; database statement; if (failure) rollback work; ... commit work; I have left out some control structures, but you get the idea. "Success" and "failure" here don't necessarily refer to the database statements; they could be talking about other conditions that arise in the application. > Michael C. De Masi - AT&T Communications (For whom I work and not speak) > 3702 Pender Drive, Fairfax, Virginia 22030 Phone: 703-246-9555 > UUCP: seismo!decuac!grebyn!paisano!demasi > "Life. Don't tell me about life." - Marvin, the paranoid android -- Jeff Lichtman at rtech (Relational Technology, Inc.) "Saints should always be judged guilty until they are proved innocent..." {amdahl, sun}!rtech!jeff {ucbvax, decvax}!mtxinu!rtech!jeff