ORACLE:阻塞
update、delete、for update都具有阻塞。
阻塞使用场景案例:
主线程执行逻辑,更新表trade_type_test,开辟新线程导出数据后,查询数据,查询的数据是主线程更新状态后的数据,而不是更新状态前的数据。
一、如果子线程查询数据,不使用阻塞,则可能会出现主线程更新数据,还没有提交,而子线程执行速度很快,已经执行到了查询这一步的情况下,导致查询出来的数据是更新状态之前的数据。
如下:
开启两个plsqldev
plsqldev(1)
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1;
ID NAME STATUS
----------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1 充值 0
SQL> UPDATE TRADE_TYPE_TEST SET STATUS = 1 WHERE ID = 1;
1 row updated
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1;
ID NAME STATUS
----------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1 充值 1
说明:更新数据,但是并未提交,在第二个plsqldev中查询出的该数据仍然status=0
plsqldev(2)
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1;
ID NAME STATUS
----------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1 充值 0
以上情况查出的数据就不正确了。
二、使用阻塞的办法解决该场景
plsqldev(2)
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1 FOR UPDATE;
以上第二个plsqldev一直处于阻塞,等待状态。直到第一个plsqldev提交后才执行该查询语句。
plsqldev(1)
SQL> commit;
Commit complete
plsqldev(1)提交后,plsqldev(2)立即查询,查询出的是更新状态后的我们所需要的数据。
plsqldev(2)
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1 FOR UPDATE;
ID NAME STATUS
----------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1 充值 1
for update也具备了阻塞,其他对该数据delete、update、for update的操作,仍然也需要等待plsqldev(2)提交后,才能执行。
SQL> SELECT * FROM TRADE_TYPE_TEST WHERE ID = 1 FOR UPDATE;
ID NAME STATUS
----------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
1 充值 1
SQL> commit;
Commit complete
plsqldev(2)未提交,做delete、update、for update操作阻塞。
plsqldev(2)提交后,做delete、update、for update立即执行。