Ari*_*MAZ 0 sql sql-server stored-procedures transactions
我想用 SP 中的 SELECT 语句锁定表中的一些行。我的 SP 中有交易。我想在 BEGIN TRANSACTION 之后锁定我选择的所有行。所以,我想在 COMMIT/ROLLBACK 之后释放这些行。
我尝试过 XLOCK、UPDLOCK、HOLDLOCK,但它们都没有达到我的预期。
这是我的示例代码...
BEGIN TRANSACTION
-- I WANT TO LOCK EMPLOYEES LIVE IN ISTANBULL
SELECT ID FROM EMPLOYEES WITH(XLOCK) WHERE CITY='ISTANBUL'
....
....
....
COMMIT
-- LOCKED ROWS SHOULD BE RELEASED AFTER COMMIT.
Run Code Online (Sandbox Code Playgroud)
有什么建议吗?
您的代码应该可以正常工作。
假设您正在选择带有 UPDLOCK/XLOCK 的行。
第一笔交易
BEGIN TRAN
SELECT ID FROM EMPLOYEES WITH(UPDLOCK, XLOCK) WHERE CITY='ISTANBUL'
--COMMIT TRAN (Stopping commit to keep the lock running)
Run Code Online (Sandbox Code Playgroud)
现在尝试在另一个窗口中运行。
第二笔交易
BEGIN TRAN
SELECT ID FROM EMPLOYEES WITH(UPDLOCK, XLOCK) WHERE CITY='ISTANBUL'
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
在您提交第一个事务之前,您的第二个事务将无法选择。因为不能在一个资源上同时应用多个 UPDLOCK 或 XLOCK。
现在,如果您使用未提交的第一个事务在没有锁定的情况下读取行,那么第一个事务不会阻止第二个事务。
第二笔交易
BEGIN TRAN
SELECT ID FROM EMPLOYEES WHERE CITY='ISTANBUL'
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
因为在第二个事务中没有应用锁,所以它不会被第一个事务 UPDLOCK 或 XLOCK 阻止。
现在为了防止任何读取与另一个读取,您需要将隔离级别更改为可序列化。
第一笔交易
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SELECT ID FROM EMPLOYEES WHERE CITY='ISTANBUL'
--COMMIT TRAN (Stopping commit to keep the lock running)
Run Code Online (Sandbox Code Playgroud)
第二笔交易
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SELECT ID FROM EMPLOYEES WHERE CITY='ISTANBUL'
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
现在第二笔交易将被第一笔交易阻止。虽然在读取期间没有应用锁,但在事务隔离级别 SERIALIZABLE 中,读取事务将阻止对同一资源的另一个事务的读取。
现在,如果您选择NOLOCK,则不存在事务锁或隔离级别来阻止您。
希望这些有帮助:)
| 归档时间: |
|
| 查看次数: |
5462 次 |
| 最近记录: |