InterBase的事务处理(转) :: modou

来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=26318 存档链接: https://web.archive.org/web/20041222123400id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=26318


modou 一个程序员的网记 <<<又一是个大清早 | 首页 | 一个很棒的开源数据库建模工具DBDesigner>>> InterBase的事务处理(转) 时间:2003-07-22 我们知道,在InterBase中任何对数据库的操作必须放在事务的上下文中进行。正确地理解事务的概念,对于掌握和使用InterBase至关重要。但是,InterBase的事务概念并没有显露在外表,它的触发器和存储过程语言也不支持事务语句,这就给很多人认识InterBase的事务造成了一定的困难。本文从InterBase的底层API函数着手和大家详细地谈一下这个问题。 在InterBase中,与事务处理密切相关的函数有: isc_start_transaction():启动一个新事务。 isc_commit_transaction():提交事务做的更改,并结束事务的执行,释放事务上下文资源。 isc_commit_retaining():提交事务做的更改,但并不结束事务,保留事务上下文资源,以便进一步使用。 isc_rollback_transaction():回退事务做的更改,结束事务的执行,释放事务的上下文资源。 当然还有其它相关函数比如处理跨多个数据库的事务等,在此没有列出。 用户对数据库的每一个请求都要放在事务中进行,也就是说事务是随着用户的请求由系统隐式调用isc_start_transaction()函数启动的,用户操作完毕,系统会根据情况隐式调用isc_commit_transaction()或isc_rollback_transaction()结束事务。 从逻辑上看,要启动一个事务,有三个步骤: 首先创建并初始化事务句柄,然后设置TPB,最后调用isc_start_transaction()。 从上面的步骤可以看出,有一个概念对启动、控制事务执行非常重要,那就是TPB,InterBase的事务参数缓冲区 。不要小看这个TPB,实际上正是TPB的众多选项决定了如何更精细的控制事务的运行。可以说,搞懂了TPB,基本上就搞懂了InterBase的事务。下面我详细的将TPB说明如下: 从底层看,TPB是一个字符数组,它的每一个元素都代表着一个事务属性,配置不同的属性将决定事务运行的不同特点。这些属性分为如下几类: 1、InterBase的事务版本号:isc_tpb_version3,InterBase内部使用,这个参数必须是TPB的第一个参数。 2、事务访问模式:控制事务能否进行读或写操作。 isc_tpb_read:只允许事务进行读操作。 isc_tpb_write:允许事务执行写操作。这也是缺省的模式。 只能设置一种访问模式,否则,后者将覆盖前者。 3、事务的隔离级别:表明并发的事务之间相互隔离的程度,也就是允许你的事务可以看到其他的事务的什么数据。 InterBase有如下几种隔离级别,分别是: ・isc_tpb_concurrency:这是最低的隔离级别,它允许当前并发事务共享表的读写权限。该属性能够充分发挥InterBase的多代结构版本事务模式的优势,提供高吞吐、高并发的性能。 ・isc_tpb_read_committed:这是比较高的隔离级别,它允许当前事务访问该事务启动后其他并发的活动事务已经提交的数据。在这种隔离级别下,不能提供数据库的一致视图。该属性能够充分发挥InterBase的多代结构版本事务模式的优势,提供高吞吐、高并发的性能。 该属性必须和isc_tpb_rec_version或 isc_tpb_no_rec_version两个更细微的属性之一配合使用。其中:isc_tpb_read_committed+isc_tpb_no_rec_version:这是缺省的精细配置,只允许事务访问已经提交的记录最新版本。如果记录还有未提交的版本存在,那么不允许事务访问该记录。可见,这种配置可能会引起事务较长时间处于等待状态,所以最好和isc_tpb_nowait属性联合使用以避免死锁。 isc_tpb_read_committed+isc_tpb_rec_version:不管记录是否存在未提交的版本,总是允许事务访问已经提交的最新的记录版本。 ・isc_tpb_consistency是最高的隔离级别,提供了串行读事务模式。在这种模式下,系统在数据表上加了锁,阻止其他事务对表的访问。 事务的隔离级别只能设置一种,否则后者覆盖前者。 事务之间的交互作用如下图: 4、锁冲突解决方案:该属性指明当事务在写期间遇到冲突时如何处理。 isc_tpb_wait:缺省的方案,表明事务必须等待直到锁资源被释放。锁释放后事务重新尝试其操作。 isc_tpb_nowait:表明事务不必等待锁释放,而代之返回一个锁冲突错误。 该属性也只能设置一种,否则后者覆盖前者。 5、表保留属性:通常情况下,只有当事务执行真正的读、写数据时才实际获得对表的某种访问权限。而表保留属性则可以让事务在启动时就获得对表的某种权限,而不必等到实际执行时刻。表保留参数有三个主要作用: 一是防止通常情况下的死锁和更改冲突,二是提供dependency锁,所谓dependency锁,就是可能被触发器或完整性约束影响的表级锁,尽管一个显式的dependency锁并不是必要的,但它能确保由于间接的表冲突而不发生更改冲突,三是在一个事务中改变一个或多个单独表的共享权限级别,如果你想单独控制对某个表的访问权限,就可以参考使用如下的参数。有效的表保留属性有: ・isc_tpb_shared、isc_tpb_lock_write:允许任何事务使用isc_tpb_write访问模式+isc_tpb_concurrency或isc_tpb_read_committed隔离级别更改数据,同时允许使用isc_tpb_read访问模式+isc_tpb_concurrency或isc_tpb_read_committed隔离级别的事务读取数据。 ・isc_tpb_shared、isc_tpb_lock_read:允许任何事务读取数据,同时允许任何使用isc_tpb_write的事务更改数据。这也是最自由的保留模式。 ・isc_tpb_protected、isc_tpb_lock_write:阻止其他事务更改数据。也就是说,那些使用isc_tpb_concurrency或isc_tpb_read_committed隔离级别的事务只能读取数据,只有当前事务可以更改数据。 ・isc_tpb_protected、isc_tpb_lock_read:禁止所有的事务更改数据,但允许所有的事务读取数据。 最后我们看一下InterBase缺省的TPB选项是什么。默认情况下,如果你不额外提供TPB参数,InterBase将使用如下的缺省值:isc_tpb_version3+isc_tpb_write+isc_tpb_concurrency+isc_tpb_wait 即允许事务读写数据、使用最低隔离级别、必须等待锁冲突释放。应该说缺省的设置并不是最好的配置。 下面让我们看一下著名的InterBase数据库管理与开发工具IBEpert使用的TPB参数:isc_tpb_read_committed isc_tpb_rec_version isc_tpb_nowait 从中我们或许能体会到一些有用的经验。 开发InterBase应用,通常情况下,大多数不外乎使用IBX和DBExpress访问。那么下面我们就分析一下IBX和DBExpress中TPB的设置情况。两者的区别是IBX能够提供更多InterBase特点的功能,访问速度比较快;DBExpress则比较通用。两者均可以用来开发多层应用。 IBX控制数据库事务使用TIBTransaction控件,默认情况下即如果你不进行额外的设置它将使用默认的TPB参数。因此,我们一般要根据实际情况进行配置。鼠标右键点击该控件,在弹出式菜单Transaction editor中配置TPB参数。共有4种情况:Snapshot、Read Committed、read_Only table stability、Read_write table stability,它们对应的TPB参数设置分别是: isc_tpb_Concurrency+ isc_tpb_nowait、isc_tpb_read_committed+ isc_tpb_rec_version+ isc_tpb_nowait、isc_tpb_read+ isc_tpb_consistency、isc_tpb_write+ isc_tpb_ Consistency。你可以根据实际应用选择具体设置。我的想法是在大规模的在线事务处理系统中(频繁地更改数据),最好使用Read Committed即isc_tpb_read_committed+ isc_tpb_rec_version+ isc_tpb_nowait模式,该模式不但能充分发挥InterBase多代结构的优势,对于一般的报表处理也能够应付。当然如果你的系统偏重于数据决策与分析,最好根据情况选择后面的两者之一。 DBExpress是Borland提供的新型的数据处理技术,它对事务的控制主要是通过TSQLConnection进行的。在该控件中,主要提供了三种标准SQL事务隔离级别,即dirty read脏读xilDIRTYREAD、read committed读提交xilREADCOMMITTED、repeatable read重复读xilREPEATABLEREAD,此外还预留了xilCUSTOM属性以便于日后扩展。如果使用DBExpress开发InterBase数据库系统,一般使用read committed读提交xilREADCOMMITTED属性,它可能相当于isc_tpb_read_committed+ isc_tpb_rec_version+ isc_tpb_nowait,以便于充分发挥InterBase的性能。 modou 发表于 2003-07-22 20:10 引用Trackback(0) | 编辑 评论 发表评论 最后更新 最近发生了很多事 一个很棒的开源数据库建模工具DBDesigner 不要沉迷于幻想,认清现实,这样才能更好的工作 没想到今天竟然收到mm的通牒了 用BrainStorm来辅助开发真不错 JEDIVCSDiff的修改 新编译了JediVCS 晕倒,终于能比较正常访问这里了 Windows的C0000218错误的修复 好难进来一次