创建表:
CREATE TABLE db_user
(
id character varying(50) NOT NULL,
age integer,
name character varying(100),
roleid character varying,
CONSTRAINT db_user_pkey PRIMARY KEY (id)
)
随便插入几条数据即可。
一、不加锁演示
1、打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;
select * from db_user where name='lisi';
输出结果:
2、再打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;
select * from db_user where name='lisi';
输出结果:
二、加锁演示(for update)
1、打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;
select * from db_user where name='lisi' for update;
输出结果:
2、再打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;
select * from db_user where name='lisi' for update;
输出结果:
查询一直处于执行中状态。
3、第一个窗口执行:
commit;
第二个窗口立即执行查询操作,结果如下:
第二个窗口记得提交commit;。
三、加锁演示(for update nowait)
1、打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;select * from db_user where name='lisi' for update nowait;
输出结果:
2、再打开一个postgreSQL的SQL Shell或pgAdmin的SQL编辑器窗口,执行:
begin;
select * from db_user where name='lisi' for update nowait;
输出结果:
不会进行资源等待,返回错误信息。
3、第一个窗口执行:
commit;
提交成功,资源锁释放。
总结:for update nowait和 for update 都会对所查询到得结果集进行加锁,所不同的是,如果另外一个线程正在修改结果集中的数据,for update nowait 不会进行资源等待,只要发现结果集中有些数据被加锁,立刻返回 “55P03错误,内容是无法在记录上获得锁.
命令说明:
begin;--开启事务
begin transaction;--开启事务
commit;--提交
rollback;--回滚
set lock_timeout=5000;--设置超时时间
注意:
连表查询加锁时,不支持单边连接形式,例如:
select u.*,r.* from db_user u left join db_role r on u.roleid=r.id for update;
支持以下形式,并锁住了两个表中关联的数据:
select u.*,r.* from db_user u, db_role r where u.roleid=r.id for update;