在OLTP的环境下使用大事务出现的问题
2008-09-03 10:01:17 来源:WEB开发网在应用环境中,常常需要保证几张表相关数据的一致性,为了应对这种需求,开发工程师常常会使用事务,把一些insert,update等语句绑在一起,形成一个事务(Transaction),比如如下的伪代码示例(事务1):
begin transaction
insert into messgae(id,col1,col2...) values(#id,#col1,#col2...);
update thread set post_count=nvl(post_count,0) + 1 where id=#v_id;
update test_user set sum_reply = sum_reply + 1 where userid=#v_userid;
end transaction
开发工程师为了实现应用数据完整性的需要,把这几条SQL绑在一起形成一个大事务,并没有什么问题。在OLTP业务发展的早期阶段,这样设计并不会遇到任何问题,并可以最大程度的保证应用层数据的完整性。但随着OLTP业务量的发展,并发访问量的快速增长,这个大事务开始出现问题,阻塞现象异常严重,导致应用服务器页面响应时间明显加长,并已影响到业务的正常运行!经过调查发现,在系统中还存在这样一个更新SQL(事务2):
update thread set view_count=nvl(view_count,0) + 1 where id=#v_id;
而这个因外界访问量的增大,执行次数异常的高。很明显,当事务1执行时,有多个语句要执行,执行时间较长,如果此时有大量的事务2相要执行,我所指的是更新相同的id的记录。那么即会发生出现大量的enqueue等待。这是采用当前事务策略下,在OLTP环境下,我们不得不面对的问题.
在刚开始出现大量锁enqueue等待时,针对事务1,事务2执行频率的不同:事务1低,事务2高。可以采用一定的策略来减少事务2的数据库执行次数,比如先将此更新放到缓存里,每隔一定的时间间隔更新到数据库里,减少事务1与事务2的碰撞机会。
更多精彩
赞助商链接