Pb的事务处理机制

一、数据库的事务处理简介

在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元,当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。

对事务的操作是这样进行的,先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。

二、PowerBuilder事务对象(Transaction Objects)

事务是PowerBuilder中自动与数据库交互的控制者,是PowerBuilder程序与数据库之间传递信息的一个结构变量,PowerBuilder会在应用开始时建立一个全局的事务对象SQLCA,但是需要指定默认的数据库连接的相关属性,当然,开发者也可以创建自己的事务。

2.1事务的生命周期
使用步骤如下:
1、定义事务对象变量
   Transaction ts1
  2、创建事务对象,为事务对象变量分配空间
   ts1 = Create Transaction
  3、指定连接信息
   ts1.DBMS=″ORACIE″ 
       ts1.Database=″DatabaseName″ 
       ts1.UserID=″UserID″ 
       ts1.DBpass=″DBpass″ 
       ts1.serverName=″serverName″ 
       ts1.LogID=″LogID″ 
       ts1.Logpass=″Logpass″
 
     如果使用SQLCA连接无需1、2步,但仍需使用本步对连接参数设置。
 
  4、连接数据库
   connect using ts1 或connect,使用SQLCA连接
 
  5、建立事务对象与对应数据窗口连接 
     dw_1.SetTransobject(ts1)

  6、取数据、更新数据 
   dw_1.retrieve()
   dw_1.update()

  7、提交或回滚事务
    COMMIT using ts1
      Rollback Using ts1
 
  8、断开连接、释放事务对象变量
    Disconnect using ts1
      Destrog using ts1

2.2 事务的成员

1、DBMS           string   所使用的数据库管理系统的名字,如Sybase,Oracle,ODBC。   
    2、Database       string   要连接的数据库名字。   
    3、UserID         string   连接数据库所用的用户名。有的DBMS不需要此项。   
    4、DBPass         string   用户连接数据库的口令。   
    5、Lock           string   这是数据库的隔离级别,一般不必给出。   
    6、LogID          string   登录到数据库服务器上的用户名,有的DBMS不需要此项,
                               但Sybase和Oracle需要指定这个参数。   
    7、LogPass        string   登录到数据库服务器上的用户口令。这个属性可设可不设,
                               但Sybase和Oracle需要指定口令。   
    8、ServerName     string   数据库服务器名。   
    9、AutoCommit     boolean  指定是否将数据库设置成自动提交所有事务,默认是False,
                               Sqlserver有效。   
   10、DBParm         string   用于向数据库传递特殊信息的属性。   
   11、SQLCode        long     指示最近一次SQL操作失败或成功。
                               返回结果值为: 0  无错误。-1  出现一个错误。 100  
                               没有检索到数据。   
   12、SQLNRows       long     最近一次SQL操作影响的行数,数据库不同其含义也不同。   
   13、SQLDBCode      long     数据库错误代码。不同的数据库的含义不同。   
   14、SQLErrText     string   相应于SQLDBCode属性中错误码的文字说明。   
   15、SQLReturnData  string   返回DBMS执行SQL的附加信息,不同的DBMS其值不同。

2.3 事务管理的应用
      
     PowerScript中常用的事务管理的语句有四个:COMMIT,ROLLBACK,CONNECT,DISCONNECT。
    当一个事务的数据库修改都成功地完成后,修改须提交给数据库,COMMIT语句是一个旧事务结束和一个新事务开始的界线。
 
   事务对象的AutoCommit属性
  
  事务对象有一个AutoCommit的属性可以使开发者简化对事务管理的操作,这一布尔型的属性可以用TRUE或FALSE来对其赋值。
    当其为真时,PowerBuilder不通过其他额外的交互就将您的SQL语句传输给后台数据库,而且执行完毕自动提交;
  当然,您可以设置AutoCommit属性为假(缺省值),使用COMMIT或ROLLBACK这样的关键词提交或回退事务;
    在大多数应用中,一部分的数据库操作是要成组提交的,而另一些则不用。因此我们可以利用AutoCommit的特性来确定事务的起点,当我们把AutoCommit的属性设为False时,系统设定此时为事务的起点。当AutoCommit设为真时,系统自动消取这一事务。因此你可以先把AutoCommit设为真,当您需要开始一个事务时,将其置为false,此刻即为事务起始点。  
  PowerBuilder内部这种事务管理的最大优点是方便,不用考虑整个事务,而只需把自己所作的修改提交或滚回即可。

三、测试
 
    测试环境pb7和sqlserver2000:
    测试表名:table_test 
    字段 xm1 varchar(20),num1 numeric(18,2)

3.1 默认设定AutoCommit=true 增加一条记录不提交

按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试',1);      
    单击按钮,系统自动的进行了Commit,事务结束。
    当前用户可以查询到增加的数据,
    其它用户也可以查询到增加的数据。
 
3.2 默认设定AutoCommit=false 增加一条记录不提交

按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试',1);       
    单击按钮,当前用户可以查询到增加的数据,表被锁住,其它用户查询处于等待状态,
因为程序没有commit;将进入假死状态,退出应用,事务自动的进行了commit,释放了
表的锁定,其它用户可以查询到增加的数据。
 
3.3 默认设定AutoCommit=true 增加两条正确的记录不提交
 
    按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试',1);
    insert into table_test  (xm1,num1) values  ( '测试2',2);   
    单击按钮,系统自动的对每个增加进行了Commit,事务结束。
    当前用户可以查询到增加的数据,
    其它用户也可以查询到增加的数据。
 
3.4 默认设定AutoCommit=true 增加一条正确的记录,一条不正确的记录,不提交

按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试2',2);
    insert into table_test  (xm1,num1) values  ( '测试','a');  
    单击按钮,发现第一条增加成功了,第二条没有成功。
    当前用户可以查询到增加的数据,
    其它用户也可以查询到增加的数据。
 
3.5 默认AutoCommit=false 增加一条正确的记录,一条不正确的记录,测试回滚

按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试2',2);
    insert into table_test  (xm1,num1) values  ( '测试','a');
    rollback; 
    单击按钮,发现没有增加成功数据;
    将rollback更改成commit,发现效果是一样;
    因为第二条是错误的,自动触发了回滚到上一个Commit的状态,所以没有增加一条记录。

下面,反过来试试。
 
3.6 默认AutoCommit=false 增加一条不正确的记录,一条正确的记录,测试回滚
 
    按钮增加事件:
    insert into table_test  (xm1,num1) values  ( '测试','a');
    insert into table_test  (xm1,num1) values  ( '测试2',2);
    rollback;
    单击按钮,发现第二条语句增加成功了。
    因为第一条是错误的,自动触发回滚,第二条语句执行正确,回滚语句也就没有触发。

3.7 默认AutoCommit=false 增加一条不正确的记录,一条正确的记录,测试同步提交

按钮增加事件:

sqlca.autocommit=false string ls_err; insert into table_test (xm1,num1) values ( '测试','a'); if sqlca.sqlcode<>0 then ls_err=sqlca.sqlerrtext rollback; messagebox('提示1',ls_err) return END IF insert into table_test (xm1,num1) values ('测试2',2); if sqlca.sqlcode<>0 then ls_err=sqlca.sqlerrtext rollback; messagebox('提示2',ls_err) return END IF commit;

这样,可以多条语句在一个事务中执行了。
【测试结论】
 
(1)如果设定AutoCommit=false,对数据的增删改需要自己提交,不然表被锁住,成为假死状态;
(2)PB事务自己加上了锁,处理了可能存在的脏读,不一致读,并发等问题,Lock属性可以不用设置了;
(3)Slqca 默认的AutoCommit属性是false,需要用户对每条增删改Sql自己加Commit;
(4)如果设定AutoCommit=true,对于需要多条一起执行的Sql语句,需要首先把AutoCommit设为false,然后在一个事务中处理;
(5)对于多条需要一起执行的Sql语句,也可以在数据库中使用存储过程处理,保证数据的一致性;
(6)数据窗口更新,只要DBERROR有错误,而事先没有做过任何COMMIT工作,那么ROLLBACK可以回滚到上次COMMIT位置,即上次COMMIT后所有的数据将被回滚;
(7)如果是直接写入SQL语句,只要数据库出现错误,那么ROLLBACK可以回滚到上次COMMIT的位置,即上次COMMIT后所有的数据将被回滚;
(8)在一个应用打开之前有任何未COMMIT的数据,都将会导致对这个表的任何操作出现资源争用的现象,即假死状态;
(9)对表的资源假死现象不会出现在任何查询语句中,即使查询语句未做提交工作,所以在查询语句中最好不要使用COMMIT;
(10)更新应该具有即时性,不要在数据还没有准备更新的时候,做一些查询/更新操作,这样会导致假死(多用户时),所以更新、插入操作应该是越接近COMMIT,ROLLBACK越好;
(11)复查的查询操作不要放到UPDATE,INSERT之间,这样会增加假死的机会。

(0)

相关推荐