LOCK(2)-TM LOCK

 

  1. TM(DML Enqueue)
    1. 修改内容的时候,结构是不应该被修改的.这是通过TM锁实现的.
      Session1:  delete u1.t1;
      Session2:  drop u1.t1
      drop table u1.t1

              *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified


这个错误提示nowait是没意义的(因为没这个语法),只是提醒不可以删除.

查询一下锁的情况:
select username,v$lock.sid,v$lock.TYPE,

trunc(id1/power(2,16)) rbs,

bitand(id1,to_number('ffff','xxxx'))+0 slot,

id2 seq,

lmode,

request

from v$lock, v$session

where --v$lock.type = 'TX'

 --and

       v$lock.sid = v$session.sid

 and v$session.username = 'SYS';


           USERNAME        SID        TYPE        RBS        SLOT        SEQ        LMODE        REQUEST

1        SYS                  159        TM        0        53133        0        3        0

2        SYS                  159        TX        10        39        450        6        0

 

TM锁住的对象是53133(v$lockid1含义为objet_id), 然后到dba_objects中查出该对象确实为u1.t1.

 

TM锁是跟对象有关的.DML修改数据的时候,一定要先获得对象上的TM锁之后,再获得事务TX(事实上相当于行锁),然后才能对锁定的行进行修改. 如果一个事务涉及到多个对象,TM锁会获得多个,TX锁在一个事务中总是一把.
 

再做个一个事务在多个表中dml操作的试验:

Session1:
Create table u1.t2 as select * from u1.t1;

Insert into u1.t1(Id) values(4);
Insert into u1.t2(id) values(4);
 

查询锁的情况,可以看到2TM锁住两个对象,但始终一个TX(但也锁住了所有的修改的行).
           USERNAME        SID        TYPE        RBS        SLOT        SEQ        LMODE        REQUEST

1        SYS                  159        TM        0        53133        0        3        0

2        SYS                  159        TM        0        53219        0        3        0

3        SYS                  159        TX        8        6        497        6        0

 

其他:

1)TM锁受参数DML_LOCKS控制,但是一个特例就是如果DML_LOCKS=0,那么并不是TM锁无法获得,而是ddl锁不允许.--某些特殊作用
2)也可以单独对一个对象禁止使用锁.ALTER TABLE xxx disable table lock;-->保护该表不被异常删除了..

SQL> alter table u1.t1 disable table lock;
SQL> drop table u1.t1;

drop table u1.t1

            *

ERROR at line 1:

ORA-00069: cannot acquire lock -- table locks disabled for T1

SQL> insert into u1.t1(id) values(1);

1 row created.

此时去查锁,只有tx,没有tm.
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面这段代码有什么问题 CKSTime gKSTime; pthread_mutex_t m_lock; CKSTime::CKSTime() { pthread_mutex_init(&m_lock,NULL); pthread_mutex_lock(&m_lock); ReflushTime(); pthread_mutex_unlock(&m_lock); } CKSTime * CKSTime::GetCurrentTime() { static unsigned long lasttick=0; pthread_mutex_lock(&m_lock); unsigned long tick = ::GetTickCount(); if (lasttick==0) lasttick=tick; if (tick==m_LastTick) { pthread_mutex_unlock(&m_lock); return(this); } if (tick>m_LastTick && (tick-lasttick)<10000) { int dtick = tick-m_LastTick+m_MSecond; m_LastTick = tick; m_MSecond = dtick%1000; dtick = dtick/1000+m_Second; m_Second = dtick%60; dtick = dtick/60+m_Minute; m_Minute = dtick%60; dtick = dtick/60+m_Hour; if (dtick<24) { m_Hour = dtick; pthread_mutex_unlock(&m_lock); return(this); } } lasttick=tick; ReflushTime(); pthread_mutex_unlock(&m_lock); return(this); } CKSTime *GetKSTime(void) { return gKSTime.GetCurrentTime(); } CKSTime::~CKSTime() { pthread_mutex_destroy(&m_lock); } void CKSTime::ReflushTime() { pthread_mutex_lock(&m_lock); struct tm klgLocalTime; time_t now; time(&now); memcpy(&klgLocalTime, localtime(&now), sizeof(klgLocalTime)); m_LastTick = ::GetTickCount(); m_Year = klgLocalTime.tm_year + 1900 ; m_Month = klgLocalTime.tm_mon + 1 ; m_Day = klgLocalTime.tm_mday; m_WeekDay = klgLocalTime.tm_wday; m_Hour = klgLocalTime.tm_hour; m_Minute = klgLocalTime.tm_min; m_Second = klgLocalTime.tm_sec; m_MSecond = m_LastTick%1000; pthread_mutex_unlock(&m_lock); } void CKSTime::ReflushTime2(void) { pthread_mutex_lock(&m_lock); ReflushTime(); pthread_mutex_unlock(&m_lock); }
最新发布
07-13
这段代码存在以下问题: 1. 在CKSTime的构造函数中,使用了pthread_mutex_lock函数来锁定互斥锁m_lock,但是在ReflushTime函数中也使用了相同的互斥锁进行加锁操作,这样可能会导致死锁的问题。 2. 在CKSTime::GetCurrentTime函数中,定义了一个静态变量lasttick,但是没有进行初始化。这样可能会导致第一次使用时的结果不可预测。 3. 在CKSTime::GetCurrentTime函数中,判断tick是否等于m_LastTick时,应该使用双等号(==)进行比较,而不是使用赋值操作符(=)。 4. 在CKSTime::GetCurrentTime函数中,返回的是指向CKSTime对象的指针,但是该指针指向的对象可能已经被销毁,从而导致悬空指针的问题。 5. 在GetKSTime函数中,返回的是指向CKSTime对象的指针,但是没有对gKSTime进行初始化,可能导致使用未初始化的对象。 6. 在CKSTime的析构函数中,使用pthread_mutex_destroy函数销毁互斥锁m_lock,但是没有进行错误处理,无法得知是否成功销毁。 7. 在CKSTime::ReflushTime函数中,使用了memcpy函数将本地时间复制到klgLocalTime结构体,但是没有对其进行错误处理,无法得知是否成功复制。 8. 在CKSTime::ReflushTime函数中,获取m_LastTick时,使用了::GetTickCount函数,但是没有提供该函数的定义,可能会导致链接错误。 9. 在CKSTime::ReflushTime函数中,对m_MSecond进行赋值时,使用了m_LastTick%1000来计算,但是m_LastTick的值未必是在0到1000之间的,可能会导致计算结果不准确。 10. 在CKSTime::ReflushTime函数中,对m_Year和m_Month的赋值操作没有进行错误处理,无法得知是否成功赋值。 11. 在CKSTime::ReflushTime2函数中,对互斥锁进行了两次加锁和两次解锁操作,这是不必要的,只需要一次即可。 以上是我对代码的分析和发现的问题,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值