是否可以使用 ADO.NET 锁定 oracle 10g 数据库表?
我有一个表,其中包含需要由多个程序获取和设置的最大值。在 C# 中,当获取旧值并更新新值时,如何锁定表一段时间?换句话说:
string sql = "lock table MaxValueTable in exclusive mode";
using (DbCommand cmd = cnctn.CreateCommand())
{
cmd.CommandText = sql;
// execute command somehow!!
}
maxValue = GetMaxValue();
SetMaxValue(maxValue + X);
sql = "lock table MaxValueTable in share mode";
using (DbCommand cmd = cnctn.CreateCommand())
{
cmd.CommandText = sql;
// execute command somehow!!
}
I have a table that contains a maximum value that needs to be get and set by multiple programs. How can I lock the table for a while when old value is got and new is updated in C#? In other words:
string sql = "lock table MaxValueTable in exclusive mode";
using (DbCommand cmd = cnctn.CreateCommand())
{
cmd.CommandText = sql;
// execute command somehow!!
}
maxValue = GetMaxValue();
SetMaxValue(maxValue + X);
sql = "lock table MaxValueTable in share mode";
using (DbCommand cmd = cnctn.CreateCommand())
{
cmd.CommandText = sql;
// execute command somehow!!
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用指定数据库的提供程序通常是一个好习惯。 Oracle 在其网站上有专门的 Microsoft.Net 提供程序,我建议使用它。请注意,所有专用提供程序都实现相同的基类,因此保留了一定的抽象级别。其次,你肯定需要一笔交易。我建议通过调用存储过程(通过executeNonQuery()或executeScalar()方法来做到这一点 - 取决于您需要的结果。
如果您不能使用存储过程(您无法创建它们)那么您必须使用提供商提供的交易 Ole 提供商和 ORacle 提供商都提供交易。
It's generally a good practice to use providers for a specified database. Oracle has a dedicated provider for Microsoft.Net on his site, I would recommend using it. Note that all dedicated providers implement the same base classess so certain level of abstraction is kept. Secondly U definately need a transaction. I'd recommend doing that by invoking a stored procedure (either by executeNonQuery() or executeScalar() methods - depending on the result U need.
If You can't use stored procedures (U can't create them) then You have to use transations offered by the provider. Both Ole provider and ORacle provider offer transaction
听起来你应该使用 Oracle Sequence - 正如我的评论中已经提到的: )
每当调用
NEXTVAL
时,它都会返回唯一的数字。如果由于某种原因您无法使用序列,只需对该行执行
UPDATE
即可。 Oracle 将锁定该行,直到您结束事务(COMMIT
或ROLLBACK
),并且所有其他更新将等待直到锁定被释放。编辑:
如果
ADO
不支持事务,您还可以使用AUTONOMOUS_TRANSACTION
:它将更新您的表以“分配”指定数量的值,并返回您分配的序列的第一个数字。下一个调用它的应用程序将收到下一个序列号。
UPDATE
会导致该行上的锁,因此其他调用必须等待该锁被释放。通过在AUTONOMOUS_TRANSACTION
内部使用COMMIT
,锁被释放,而你自己的事务不会受到影响。Sounds like you should be using an Oracle Sequence instead - as already mentioned in my comment :)
It will return unique numbers whenever calling
NEXTVAL
.If for some reason you cant' use a sequence, just perform an
UPDATE
on that row. Oracle will lock that row until you end your transaction (COMMIT
orROLLBACK
) and all other updates will wait until the lock is released.EDIT:
If transactions are not supported in
ADO
, you could also put that into an Oracle Procedure using anAUTONOMOUS_TRANSACTION
:It will update your table to "allocate" the specified number of values, and return the first number of the sequence you allocated. The next application that calls it will receive the next sequence number.
The
UPDATE
causes a lock on that row, so other calls have to wait for that lock to be released. By usingCOMMIT
inside theAUTONOMOUS_TRANSACTION
, the lock is released, while your own transaction will not be affected.有一个锁表命令
注意:在结束事务之前你不能重置锁。因此,如果您锁定了表,则无法将其解锁。
There is a lock table command
Note: you can't reset a lock until you end the transaction. So if you locked the table, you can't unlock it.
要在获取锁的语句之后保留锁,您需要一个事务。
To keep the lock after the statement that takes it you need a transaction.
您可以尝试另一种方法。首先在表上启用表锁定。假设我的桌子是
T
。然后现在,您可以选择,任何其他选择都会等待,因为您有锁。
因此,另一个会话中其他位置的任何选择命令都不会返回并等待锁被释放。请记住,您需要执行
COMMIT
来释放锁。You can try another method. First enable table locking on the table. Say my table is
T
. ThenNow, you can select, and any other select will wait, because you have a lock.
So, any select command else where in another session will not return and wait for the lock to be released. Remember, you need to do
COMMIT
to release the lock.Oracle 可以自行处理锁定。尽可能尝试使用数据库功能。
序列是首选方式在 Oracle 中,上面的评论会告诉你。
Oracle can handle locking itself. Try to use Database features as far as possible.
Sequence is the preferred way in Oracle as comments above will tell you.