pb transaction使用完后忘记disconnect的严重后果

简介:         很多人都明白,transaction使用完后忘记disconnect的话,数据库服务端的session连接不会释放,从而浪费了服务器资源。

        很多人都明白,transaction使用完后忘记disconnect的话,数据库服务端的session连接不会释放,从而浪费了服务器资源。其实这只是一部分后果。如果粗心大意,还会造成更大的影响。

        先来做个测试,我新建了一个窗口w_test。在窗口上放置两个按钮cb_1和cb_2。

        cb_1的clicked事件下面定义transaction sqlca1,故意漏掉了disconnect,代码如下:

                   long ll_count
                   transaction sqlca1
                  sqlca1= create transaction
                  sqlca1.DBMS = "MSS Microsoft SQL Server"
                  sqlca1.Database = "his2015"
                  sqlca1.LogPass = "sasasa"
                  sqlca1.ServerName = "."
                  sqlca1.LogId = "sa"
                  sqlca1.AutoCommit = False
                  sqlca1.DBParm = ""
                  connect using sqlca1;
                  messagebox('',string(sqlca1.sqlcode) +sqlca1.sqlerrtext)
                 destroy sqlca1

       定义long ll_count的目的是为了和cb_2的变量一样,这样才能保证sqlca1和sqlca2使用到相同的内存

      cb_2的clicked事件下面定义一个transaction sqlca2,故意漏掉connect,代码如下:

             transaction sqlca2
             long ll_count
             sqlca2 = create transaction
             select count(*) into :ll_count from AAAA using sqlca2;
             messagebox('',string(sqlca2.sqlcode)+sqlca2.sqlerrtext)
             messagebox('',ll_count)

        很多人可能都会说,cb_2的clicked事件下面的sqlca2没有连接到数据库,select不可能查询到数据,但是通过先点击cb_1再点击cb_2,程序运行的结果是查询到了数据。

         下面我将解释一下原理:

         cb_1被点击完之后,sqlca1对象占据了系统内存,但是随着cb_1的clicked事件执行完毕,sqlca1被销毁。相对应的内存也将会被重新使用。

         cb_2被点击完之后,系统会给sqlca2对象分配内存。两个按钮先后被点击,中间没有执行过别的操作。所以sqlca2被分配的内存刚好使用了sqlca1原先使用的那部分内存。而数据库的连接信息是保存在内存中的。所以即便sqlca2没有执行连接到数据库的操作,使用的时候也能够连接到sqlca1所连接的那个数据库。

       为了进一步验证我分析的是正确的。我将cb_1的clicked事件修改如下:

             long i
             transaction sqlca1,sqlca2
             sqlca1= create transaction
             sqlca1.DBMS = "MSS Microsoft SQL Server"
             sqlca1.Database = "his2015"
             sqlca1.LogPass = "sasasa"
             sqlca1.ServerName = "."
             sqlca1.LogId = "sa"
             sqlca1.AutoCommit = False
             sqlca1.DBParm = ""
             connect using sqlca1;
             messagebox('',string(sqlca1.sqlcode) +sqlca1.sqlerrtext)
            destroy sqlca1

            sqlca2= create transaction
            sqlca2.DBMS = "O84 Oracle8/8i (8.x.4+)"
            sqlca2.LogPass = "bsoft"
            sqlca2.ServerName = "GM"
            sqlca2.LogId = "portal_his"
            sqlca2.AutoCommit = False
            sqlca2.DBParm = "PBCatalogOwner='portal_his',CommitOnDisconnect='No'"
            connect using sqlca2;
            messagebox('',string(sqlca2.sqlcode) +sqlca2.sqlerrtext)

            disconnect using sqlca2;

            destroy sqlca2

        当执行到connect using sqlca2;的时候,系统返回的错误是transaction already connected。这也充分验证了sqlca1和sqlca2 使用了相同的内存,并且数据库的连接信息是保存在内存中的。这样的后果就是由于sqlca1忘记 了disconnect,即便sqlca2写的很正确,也无法连接到oracle数据库了,而且connect using sqlca2如果不判断是否成功直接使用的话,感觉在操作oracle数据库,其实是操作了sqlserver数据库。pb的帮助文档里面也提到了无论是connect 还是 disconnect都要判断是否执行成功。而很多程序员都不会去判断的,所以程序的严谨性是很重要的。

目录
相关文章
|
数据库
TortoiseSVN 执行清理( cleanUp )失败的解决方案
目前我们这边的内网代码是通过 TortoiseSVN 进行版本管理的,平时用着也挺好的,没碰到什么大问题。
494 0
TortoiseSVN 执行清理( cleanUp )失败的解决方案
|
2月前
|
关系型数据库 MySQL 测试技术
当update修改数据与原数据相同时会再次执行吗
当update修改数据与原数据相同时会再次执行吗
26 1
|
2月前
|
关系型数据库 MySQL 测试技术
MySQL中,当update修改数据与原数据相同时会再次执行吗
MySQL中,当update修改数据与原数据相同时会再次执行吗
13 0
|
4月前
tp6使用事务正常插入但是却显示失败的提示
tp6使用事务正常插入但是却显示失败的提示
35 0
|
11月前
|
SQL 存储 Java
无法创建 XA 控制连接。错误:“找不到存储过程 'master..xp_sqljdbc_xa_init_ex'
另一篇博客springboot+jta+atomikos分布式多数据源事务管理 (SQLserver)中出现的这个错误
|
12月前
|
SQL Oracle 关系型数据库
|
关系型数据库 MySQL 测试技术
面试官:MySQL 中 update 更新,数据与原数据相同时会执行吗?大部分人答不上来!
面试官:MySQL 中 update 更新,数据与原数据相同时会执行吗?大部分人答不上来!
160 0