Board index » delphi » Manually unlocking rows in a database

Manually unlocking rows in a database


2005-04-26 10:41:55 AM
delphi73
Hello,
What happens to a row's status (ie locked/unlocked) if the client app which
initiated the lock is abruptly closed (e.g. through Windows Task Manager)?
Does Interbase maintain the lock on the row? If so, are the locks maintained
through a backup/restore process?
Is there a way to manually unlock rows in a database through IBConsole or
the command line in Windows?
Additionally, when the restore was performed several times using the same
restore settings and GBK file the file size was often reported as being
different. There were also slightly different messages on each restore. What
can this be attributed to?
I'm currently using IB6.5 on Windows XP SP2 (HyperThreading and System
Restore disabled).
Regards,
William O.
 
 

Re:Manually unlocking rows in a database

If the connection to the client is lost the transaction will be rolled
back. When a transaction ends all of its locks are released.
The only way to unlock rows is to commit or rollback the transaction
that holds the locks.
To manually lock a row start a transaction then set any field in the
row to its current value. This leaves the row locked but unchanged.
It is impossible to answer your questions about the backup without more
detailed information.
--
Bill Todd (TeamB)
 

Re:Manually unlocking rows in a database

Bill Todd writes:
Quote
To manually lock a row start a transaction then set any field in the
row to its current value. This leaves the row locked but unchanged.
I thought that it was impossible to lock a row in InterBase in the
conventional sense of preventing another user from performing an update
on it ? Isn't that the whole basis of IBs
multi-generational-architecture ? If user A starts a transaction and
then user B starts a transaction on the same row and user B commits
before user A, user B wins and user A gets rolled back. Or have I been
doing this wrong for the past 11 years ?
 

Re:Manually unlocking rows in a database

SimonW writes:
Quote
Bill Todd writes:

>To manually lock a row start a transaction then set any field in the
>row to its current value. This leaves the row locked but unchanged.

I thought that it was impossible to lock a row in InterBase in the
conventional sense of preventing another user from performing an
update on it ? Isn't that the whole basis of IBs
multi-generational-architecture ?
No. You are thinking of the fact that *readers* don't block writers in
IB. But writers block writers.
In a two-phase locking architecture simply reading a row (or something
on the same page, table, etc.) can block a writer, and that doesn't
happen in IB.
Quote
If user A starts a transaction and
then user B starts a transaction on the same row and user B commits
before user A, user B wins and user A gets rolled back.
That is incorrect. If A updates first, then B will either fail or
wait, depending on the wait mode of B's transaction. If B waits then it
will only succeed if A's transaction is rolled back.
-Craig
--
Craig Stuntz [TeamB] . Vertex Systems Corp. . Columbus, OH
Delphi/InterBase Weblog : blogs.teamb.com/craigstuntz
 

Re:Manually unlocking rows in a database

So what happens when the client app is terminated with task manager without
it being able to tell IB to rollback a transaction? Is the transaction still
there with locks on the rows it selected? Is the transaction rolled back
[if/]when a connection dropout is detected?
Is there some command I can run somewhere that will simply unlock the entire
database? I.e. unlock all rows in all tables and/or rollback all current
transactions in one command. I'd do this after a transaction recovery if
it didn't find pending transactions.
~ William O.
"Craig Stuntz [TeamB]" <XXXX@XXXXX.COM [a.k.a. acm.org]>wrote
in message news:426e35c1$XXXX@XXXXX.COM...
Quote
SimonW writes:

>Bill Todd writes:
>
>>To manually lock a row start a transaction then set any field in the
>>row to its current value. This leaves the row locked but unchanged.
>
>I thought that it was impossible to lock a row in InterBase in the
>conventional sense of preventing another user from performing an
>update on it ? Isn't that the whole basis of IBs
>multi-generational-architecture ?

No. You are thinking of the fact that *readers* don't block writers in
IB. But writers block writers.

In a two-phase locking architecture simply reading a row (or something
on the same page, table, etc.) can block a writer, and that doesn't
happen in IB.

>If user A starts a transaction and
>then user B starts a transaction on the same row and user B commits
>before user A, user B wins and user A gets rolled back.

That is incorrect. If A updates first, then B will either fail or
wait, depending on the wait mode of B's transaction. If B waits then it
will only succeed if A's transaction is rolled back.

-Craig

--
Craig Stuntz [TeamB] . Vertex Systems Corp. . Columbus, OH
Delphi/InterBase Weblog : blogs.teamb.com/craigstuntz
 

Re:Manually unlocking rows in a database

William O. writes:
Quote
So what happens when the client app is terminated with task manager
without it being able to tell IB to rollback a transaction? Is the
transaction still there with locks on the rows it selected? Is the
transaction rolled back [if/]when a connection dropout is detected?
Yes and no. IB used to detect dropped clients, but a bug in the
Windows TCP/IP stack caused a memory leak in a Windows device driver
when it did this. The result was that if you had one or more dropped
clients, the server would slowly leak memory until it ran out.
That wasn't good, so the automatic check was turned off by default,
although you can reenable it in ibconfig. Better, though, is to use an
UPDATE statement against TMP$ATTACHMENTS -- IIRC you set
TMP$STATE to 'KEEPALIVE' or something like that. You can also do it by
pushing a button in performance monitor.
Quote
Is there some command I can run somewhere that will simply unlock the
entire database? I.e. unlock all rows in all tables and/or rollback
all current transactions in one command.
You can forcibly roll back all active transactions like this:
UPDATE TMP$TRANSACTIONS SET TMP$STATE = 'ROLLBACK'
WHERE TMP$STATE = 'ACTIVE' AND [some condition to exclude your own
transaction here]
This will annoy your users, but it will do what you want.
Quote
I would do this after a
transaction recovery if it didn't find pending transactions.
You will only have in-limbo transactions if you are using multi-DB
transactions; most people don't do this.
--
Craig Stuntz [TeamB] . Vertex Systems Corp. . Columbus, OH
Delphi/InterBase Weblog : blogs.teamb.com/craigstuntz
How to ask questions the smart way:
www.catb.org/~esr/faqs/smart-questions.html