DATA Step, Macro, Functions and more

%trylock and Error condition: full message

Reply
Respected Advisor
Posts: 3,899

%trylock and Error condition: full message

Hi

I have to implement concurrent write access to a SAS table (control table) without SAS\Share (not licensed) – SAS9.2 under UNIX.

I have in principal a working solution based on the %trylock macro as documented under http://www.lexjansen.com/pharmasug/2005/posters/po33.pdf

My problem is:
In case the table is locked the macro throws an error. Also that execution goes on and everything works I can’t accept Error messages in the log nor a job to end different than with an Error condition of zero.

I can’t figure out how to achieve this suppression of Errors – especially the ones written to the log.
I could save the error status at the beginning of the macro and re-set it at the very end of the macro – but what should I do with the log?

Any suggestions would be really welcome (it starts to drive me nuts)!

The way I test the macro is to open 2 SAS session. In the first one I open the table used for testing (sashelp.class), in the second session I call the macro as below (and then I go back to the first session and close the table).

%macro trylock(member=,timeout=10,retry=1);
%local starttime;
%let starttime = %sysfunc(datetime());
%do %until(&syslckrc LE 0
or %sysevalf(%sysfunc(datetime()) GT (&starttime + &timeout)));
%put trying open ...;
data _null_;
dsid = 0;
do until (dsid GT 0 or datetime() GT (&starttime + &timeout));
dsid = open("&member");
if (dsid = 0) then rc = sleep(&retry);
end;
if (dsid GT 0) then rc = close(dsid);
run;
%put trying lock ...;
lock &member;
%put syslckrc=&syslckrc;
%end;
%mend trylock;

%trylock(member=sashelp.class,timeout=60,retry=5);

lock sashelp.class clear;


The macro as given above is exactly what has been published in the link given.

The error I'm getting if a table is locked:

trying lock ...
ERROR: A lock is not available for SASHELP.CLASS.DATA.
syslckrc=70031

As soon as I unlock the table in my other SAS session the following happens:

trying lock ...
NOTE: SASHELP.CLASS.DATA is now locked for exclusive access by you.
syslckrc=0
36
37 lock sashelp.class clear;
NOTE: SASHELP.CLASS.DATA is no longer locked by you.


So as already described: The macro works as such but I end up with Errors which shouldn't be there.
It's the LOCK statement causing the issues and I still haven't found a way to capture the error conditions.

Thanks in advance
Patrick

Message was edited by: Patrick Message was edited by: Patrick
Super Contributor
Super Contributor
Posts: 3,174

Re: %trylock and Error condition

Exactly what SAS error are you getting in your log? Preferably share the SAS code in your SASLOG output, pasted as a post-reply with all code exposed, otherwise we are left guessing about the error you are concerned about.

Scott Barry
SBBWorks, Inc.
N/A
Posts: 0

Re: %trylock and Error condition

if (dsid = 0) then rc = sleep(&retry);
end;
if (dsid GT 0) then rc = close(dsid);
run;
%put trying lock ...;
lock &member;
%put syslckrc=&syslckrc;
%end;
%mend trylock;

Web Design Brisbane
Respected Advisor
Posts: 3,899

Re: %trylock and Error condition

Sam

I believe part of your post got "truncated".

From what I see: One of the issues is that OPEN returns a value NE 0 even if the table is opened in a second EG session.

That's why data _null_ suggested to use FOPEN.

Thanks
Patrick
Valued Guide
Posts: 2,175

Re: %trylock and Error condition

Patrick
some of your macro is not appearing on the forum because the syntax uses less-than or greater-than symbols - normally reserved for "forum-markup". If you replace the symbols as suggested in that in a posting I can't find right now, with & LT; or just use the mnemonic LT for < etc. then we would be more able to see what is in your macro
It is hard work deciphering it from the "Quote Original" version that follows .
>
> %macro trylock(member=,timeout=10,retry=1);
> %local starttime;
> %let starttime = %sysfunc(datetime());
> %do %until(&syslckrc <= 0
> or %sysevalf(%sysfunc(datetime()) > (&starttime +
> &timeout)));
> %put trying open ...;
> data _null_;
> dsid = 0;
> do until (dsid > 0 or datetime() > (&starttime +
> &timeout));
> dsid = open("&member");
> if (dsid = 0) then rc = sleep(&retry);
> end;
> if (dsid > 0) then rc = close(dsid);
> run;
> %put trying lock ...;
> lock &member;
> %put syslckrc=&syslckrc;
> %end;
> end trylock;
>
> %trylock(member=sashelp.class,timeout=60,retry=5);
>
> lock sashelp.class clear;
>
>


peterC
SAS Super FREQ
Posts: 8,743

Re: %trylock and Error condition

Peter:
http://support.sas.com/forums/thread.jspa?messageID=27609毙

Use the [pre] and [/pre] tags around your code and output in order to maintain indenting and spacing. Use &lt; for < and &gt; for > symbols...

cynthia
Valued Guide
Posts: 2,175

Re: %trylock and Error condition

Thank You Cynthia
that link is now added to the top of my favourites :-)

peter
Respected Advisor
Posts: 3,777

Re: %trylock and Error condition: full message

The program works as I expect it to, which may be a bit odd. If the program times out waiting for a lock then it still executes the LOCK statement, which I don't think you want. If you want a different action just modify it to maybe, print a message and ENDSAS when it times out.
Respected Advisor
Posts: 3,899

Re: %trylock and Error condition: full message

Hi data _null_

I want the macro to try and lock the table - and if not successful to wait a defined time and then try again to lock the table - until either the total time for trials runs out or a lock is successful.

My "only" problem is that if the lock is not successful a error message is written to the log and I haven't found a way to suppress this.

No error condition (code) is generated in 'my' UNIX environment so the issue is at least only on the level of 'ugly'.

To be more precise: &syscc is not affected and stays 0 but somewhere the error condition must be saved as in the end of the log the errors are mentioned.

What I'm looking for is to suppress the log error message caused by an unsuccessful lock statement and not to write it to the log. It would already be o.k. if I could suppress any log messages while the macro executes and not to mention any errors in the end of the log.

Interesting is also that if I use 'lock list; in a Win32 environment then the log tells me that no one is locking the DS (even though I have it open in a second EG session), but when I submit a 'lock ;' I'm getting the all to well known error message.

Any suggestions?

Thanks
Patrick
Respected Advisor
Posts: 3,777

Re: %trylock and Error condition: full message

> Hi data _null_
>
> I want the macro to try and lock the table - and if
> not successful to wait a defined time and then try
> again to lock the table - until either the total time
> for trials runs out or a lock is successful.
>
> My "only" problem is that if the lock is not
> successful a error message is written to the log and
> I haven't found a way to suppress this.

The macro is designed to use OPEN to TEST if a LOCK can be obtained. If a lock can be obtain by sucessfully opening the data set or the loop times out the lock is attempted. This is a flaw in the code in my opinion. I think you should modify the code to NOT attempt the lock if the loop times out. You know you can't get a lock so why try. This will fix the ERROR problem. Then you can take action as needed because you can't get the LOCK within the time limit.
Respected Advisor
Posts: 3,777

Re: %trylock and Error condition: full message

Ok, forget that.

I don't think OPEN will work I think you will need FOPEN in Update mode.

My testing shows that if the data set is open in say EG then OPEN will not show that. However if you create a FILEREF that points to the data set and use
[pre]FOPEN(fileref,'U')[/pre]
the function will return "file in use" and you can determine if a LOCK would fail or not.
Respected Advisor
Posts: 3,899

Re: %trylock and Error condition: full message

Hi data _null_

I made the same observation with OPEN. Kind of weird.

Thanks for the tip with FOPEN. I'll try this.

Thanks
Patrick
Respected Advisor
Posts: 3,899

Re: %trylock and Error condition: full message

FOPEN() did the job.

Thanks again data _null_

If anybody is interested in my version of the %trylock macro please let me know and I post it here (still finalising it).
Contributor
Posts: 28

Re: %trylock and Error condition: full message

Hi Patrick,

Can you please post your tested version for %trylock macro.

Thanks in adavnce.

Jeeth

Respected Advisor
Posts: 3,899

Re: %trylock and Error condition: full message

Hi Jeeth

That's now almost 3 years ago...

What I remember is that even after implementing all the good stuff data null suggested I still found cases during testing where the macro didn't behave as required. I ended up with running the jobs in sequence and "flagged" %trylock as an approach I'm no more trying to use in the future.

Thanks

Patrick

Ask a Question
Discussion stats
  • 16 replies
  • 2915 views
  • 1 like
  • 9 in conversation