Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.misc -> Re: lock Oracle db objects, but only a lock for others?
"Bob Kilmer" <rprgrmr_at_yahoo.com> wrote in message
news:FbHoa.222550$o8.3779878_at_twister.tampabay.rr.com...
> "Daniel Morgan" <damorgan_at_exesolutions.com> wrote in message
> news:3EA32BBB.1A412583_at_exesolutions.com...
> > Eric Fortin wrote:
> >
> > > "Daniel Morgan" <damorgan_at_exesolutions.com> wrote in message
> > > news:3EA31A5F.C26DAB1A_at_exesolutions.com...
> > > > > > On Error Goto
> > > > >
> > > > > What is the correct way to Error Handle in VB6?
> > > >
> > > > To handle the errors in the back-end, or middle-tier ifone exists:
Not
> in
> > > the
> > > > front-end. VB should only be used to display messages returned from
> the
> > > serer.
> > >
> > > >
> > > > > >
> > > > > > If things like this have been written expect that the entire
code
> base
> > > > > needs to
> > > > > > be rewritten.
> > > > > >
> > > > >
> > > > > Can you please give an example of a correct construction for VB6
and
> > > Oracle?
> > > > >
> > > > > (or is it the order, begin trans followed by error handling)
> > > > > (or is it that vb6 should not be used with Oracle)
> > > > >
> > > > > I guess I'm not clear on how it should be done.
> > > > >
> > > > > Thanks.
> > > >
> > > > No problem. I teach an entire certificate program, three quarters,
at
> the
> > > > University of Washington on the subject. So I'll just include all of
> that
> > > > information here in this usenet post
> > > >
(http://www.outreach.washington.edu/extinfo/certprog/oad/oad_crs.asp)
> just
> > > > kidding. Seriously this is not
> > > > something that can be done generically. Just to give you an example
of
> > > what I
> > > > would consider minimal information required to construct Oracle
error
> > > handling
> > > > ... I would say that you must understand all of the following:
> > > >
> > > > TooManyDays EXCEPTION;
> > > > EXCEPTION WHEN TooManyDays THEN
> > > > EXCEPTION WHEN NO_DATA_FOUND THEN
> > > > EXCEPTION WHEN OTHERS THEN
> > > > PRAGMA EXCEPTION_INIT
> > > > RAISE;
> > > > RAISE_APPLICATION_ERROR(-20001, 'Date Can Not Be In The Future');
> > > > AUTONOMOUS TRANSACTIONS
> > > >
> > > > And likely I'll think of something I missed as soon as press the
SEND
> > > button.
> > > >
> > > > Daniel Morgan
> > > >
> > >
> > > On error goto is in the VB6 code
> > >
> > > if that exception is thrown in the db and not handled in the VB app,
the
> vb
> > > app will get a terminating ora-440 error. (Then, especially if no
begin
> > > trans, all the sql up to that point will be auto committed and the sql
> after
> > > that 440 error will never be executed)
> > >
> > > Here is the Oracle Doco ( bottom of the page): on how to do it with
Ora
> OLE
> > > DB.
> > >
> > >
>
(http://download-west.oracle.com/docs/cd/B10501_01/win.920/a95498/using.htm#
> > > 1006186)----code sample:Dim Oracon As ADODB.Connection
> > > Dim recset As New ADODB.Recordset
> > > Dim cmd As New ADODB.Command
> > > Dim param1 As New ADODB.Parameter
> > > Dim param2 As New ADODB.Parameter
> > > Dim objErr As ADODB.Error
> > > Dim Message, Title, Default, EmpNoValue
> > >
> > > Message = "Enter an employee number (5000 - 9000)"
> > > Title = "Choose an Employee"
> > > Default = "7654"
> > >
> > > On Error GoTo err_test
> > >
> > > EmpNoValue = InputBox(Message, Title, Default)
> > > If EmpNoValue = "" Then Exit Sub
> > > If EmpNoValue < 5000 Or EmpNoValue > 9000 Then EmpNoValue = 7654
> > >
> > > Set Oracon = CreateObject("ADODB.Connection")
> > > Oracon.ConnectionString = "Provider=OraOLEDB.Oracle;" & _
> > > "Data Source=exampledb;" & _
> > > "User ID=scott;" & _
> > > "Password=tiger;"
> > >
> > > Oracon.Open
> > > Set cmd.ActiveConnection = Oracon
> > > Set param1 = cmd.CreateParameter("param1", adSmallInt, adParamInput, ,
> > > EmpNoValue)
> > > cmd.Parameters.Append param1
> > > Set param2 = cmd.CreateParameter("param2", adSmallInt, adParamOutput)
> > > cmd.Parameters.Append param2
> > >
> > > ' Enable PLSQLRSet property
> > > Cmd.Properties ("PLSQLRSet") = TRUE
> > >
> > > cmd.CommandText = "{CALL Employees.GetDept(?, ?)}"
> > > Set recset = cmd.Execute
> > >
> > > ' Disable PLSQLRSet property
> > > Cmd.Properties ("PLSQLRSet") = FALSE
> > >
> > > MsgBox "Number: " & EmpNoValue & " Dept: " &
> recset.Fields("deptno").Value
> > >
> > > Exit Sub
> > >
> > > err_test:
> > > MsgBox Error$
> > > For Each objErr In Oracon.Errors
> > > MsgBox objErr.Description
> > > Next
> > > Oracon.Errors.Clear
> > > Resume Next
> > >
> > > ----End code sample.
> > >
> > > Is this incorrect?
> >
> > Properly handled errors in the database never produce errors in a
> front-end.
> > That you are handling errors as you are indicates the database is not
> handling
> > them: Nothing more.
> >
> > Daniel Morgan
> >
> >
>
> I only mentioned error handling at all (On Error Goto!) to emphasize that
it
> is so difficult in this app to be sure that a lock is on or off, it is
> necessary to be ready for an error. Whether it is handled in VB or Oracle
or
> by careful routing of the spaghetti or at all is beside my point.
>
> The code I walked into looks something like the following. Even if you
have
> never heard of Oracle, you can see that this is a bad idea.
>
>
> >> 'rollback to end "select for update" lock
> '(__called code__)
> >> 'setting and removing locks all the while until
> '(__back to calling code__)
> 'do stuff
> 'call other code
>
>
I didn't comprehend your situation the first time, so let me make sure I understand.
The simple answer is that oracle has exceptional row level locking (unlike sql server).
Thus,
you could eliminate the flagging altogether.
ie:
You could create a recordset
select [cols] from emp [ + where clause] for update
All the rows (and only those rows) retreived in the recordset will be locked to that user that first accesses them
When the second (and third, and forth, etc) users run that same sql, they will not get access to those rows until the previous recordset releases them. Oracle handles all the locking for you. You have to do nothing. The subsequent client ws (workstation) just waits for the previous client ws to complete.(Oracle's row level locking is so fine grained, that user1 can get one set of rows, lock them, and user 2 can get a different set of rows and lock them without affecting either user --as long as the recordsets (cursors, in oraclespeak) do not access any of the rows in another active cursor).
However, there is one potential problem:
The second, third, (...) client ws all 'hang' (Not Responding, in the task manager), waiting for the previous recordset to clear when one of the retreived rows is already locked by a previous recordset. The only way to get the machine to 'respond' is end the task or wait for the previous user to commit, (update in some cases) or rollback. In the real world, this can be a problem: ie: the first user gets the records, two other users subsequently execute the same query, the workstation hangs on users 2 and 3 (because the first user has them), and during this process, user 2 decides to get a cup of coffee and restroom, and then gets side tracked. User 1 releases the recordset, and because the locks are created and released FIFO, user 3 (who really needs the records) has to wait and wait until user 2 gets back or someone kills the session.
If it were me, I would not mess with the flags you are talking about (impossible to read and maintain and debug). Let oracle handle the locking, and force the person in charge to enforce the no walking away rules.
If it is really a problem, and you get 'Not Responding' complaints, I'm afraid you do need some redesign. (and not of the flag sort)--(and, btw, in this case the begin-commit trans is essential, as you will have users that will do the ctrl-alt-delete and end the task after a millisecond passes).
Also, Oracle is smart enough not to allow the same application to lock itself out (deadly embrace). (however, if you execute the same for update query in a vb6 app and sqlplus on the same workstation at the same time, oracle will lock the records appropriately!)
Hopefully this helped a little.
E Received on Sun Apr 20 2003 - 22:57:51 CDT
![]() |
![]() |