{"id":294,"date":"2010-08-19T20:19:23","date_gmt":"2010-08-20T01:19:23","guid":{"rendered":"http:\/\/anvil-of-time.com\/wordpress\/?p=294"},"modified":"2021-03-09T08:02:42","modified_gmt":"2021-03-09T13:02:42","slug":"powerbuilder-database-transactions-using-pfc-n_tr","status":"publish","type":"post","link":"https:\/\/anvil-of-time.com\/powerbuilder\/powerbuilder-database-transactions-using-pfc-n_tr\/","title":{"rendered":"PowerBuilder \u2013 Database transactions using PFC n_tr"},"content":{"rendered":"<p>Here is a relatively painless way to handle transaction processing in your Powerbuilder application. This code assumes the use of the PFC but could be adapted without too much trouble.<\/p>\n<p>This will work with the following database connections:<\/p>\n<p>ADO.NET<br \/>\nASE, SYC and SYJ Sybase Adaptive Server Enterprise<br \/>\nDIR Sybase DirectConnect<br \/>\nI10 Informix<br \/>\nIN9 Informix<br \/>\nJDB JDBC<br \/>\nODBC (if driver and back-end DBMS support this feature)<br \/>\nOLE DB<br \/>\nSNC SQL Native Client for Microsoft SQL Server<\/p>\n<p>The process involves the AutoCommit database preference. The Powerbuilder default is to set this to False which means that SQL statements are issued inside a transaction. Powerbuilder issues a BEGIN TRANSACTION statement at the start of a connection and issues another BEGIN TRANSACTION statement after each COMMIT or ROLLBACK statement. In our case the AutoCommit is set to <strong>True <\/strong>so we control the transactions.<\/p>\n<p>In the n_tr object (or whatever your pfc based transaction object is called) make the following changes:<\/p>\n<p>public function long of_begin ();<\/p>\n<pre name=\"code\" class=\"VB\">\/* Issues a begin transaction by changing the autocommit flag from true to false. \nThe assumption is that the initial connection is made with\nthe autocommit flag set to true. Changing autocommit from true to false\nforces the start of a transaction.\n*\/\nlong\tll_rc = -10\nthis.SQLCode = 0\nthis.SQLErrtext = &#039;&#039;\nif of_IsConnected() then\n\tthis.autoCommit = false\n\tll_rc = this.SQLCode\nend if\nreturn ll_rc<\/pre>\n<p>public function long of_end<\/p>\n<pre name=\"code\" class=\"VB\">\/* The initial connection is made with autocommit = true. The of_start()\nmethod changes autocommit from true to false, which begins the \ntransaction. Calling of_end() changes the autocommit from false back\nto true, which commits the transaction if it had not previously been\nrolled back by a call to of_rollback(). This method is called by\nboth of_commit() and of_rollback and need not be called directly.\n*\/\n\nlong\tll_rc = -10\n\nif of_IsConnected() then\n\tthis.autoCommit = true\n\tll_rc = this.SQLCode\nend if\n\nreturn ll_rc<\/pre>\n<p>public function long of_commit<\/p>\n<pre name=\"code\" class=\"VB\">\/* Copied method from ancestor and changed &quot;commit using this&quot; to\na call to of_end(). The initial connection is made with autocommit\nset to true. Calling of_begin() changes autocommit to false, which issues\na begin transaction statement. When of_commit() is called, the\ntransaction is commited by of_end() by chaning autocommit back to true.\n*\/\n\nlong\tll_rc = -10\nstring\tls_name\n\nif of_IsConnected() then\n\t\/\/ If SQLSpy service is on, add to the history\n\tif IsValid (gnv_app) then\n\t\tif IsValid (gnv_app.inv_debug) then\n\t\t\tif IsValid (gnv_app.inv_debug.inv_sqlspy) then\n\t\t\t\tls_name = this.is_Name\n\t\t\t\tif Len (ls_name) = 0 then\n\t\t\t\t\tls_name = this.ClassName()\n\t\t\t\tend if\n\t\t\t\tgnv_app.inv_debug.inv_sqlspy.of_SQLSyntax (&quot;Commit using &quot; + ls_name )\n\t\t\tend if \n\t\tend if\n\tend if\n\n\t\/\/\tcommit using this;\n\t\/\/\tll_rc = this.SQLCode\n\tll_rc = this.of_end()\nend if\n\nreturn ll_rc<\/pre>\n<p>public function long of_rollback<\/p>\n<pre name=\"code\" class=\"VB\">\/* Rollback the transaction the pfc way, then call of_end() to reset\nthe autocommit flag back to true. (Note: This forces an un-needed\nbegin tran and commit.)\n*\/\n\nlong ll_return\n\n\/\/ call ancestor method\nll_return = super::of_rollback()\n\n\/\/ End the transaction.\nthis.of_end()\n\nreturn ll_return<\/pre>\n<p>Within the application code you then use the following code when you want to save data to the database. Naturally you need to use your transaction name if you created one other than the global transaction object SQLCA<\/p>\n<p>Prior to update(s) being issued.<\/p>\n<pre name=\"code\" class=\"VB\">\/\/begin transaction\nIF (sqlca.of_begin( ) &lt; 0) THEN\n    messagebox(&#039;Database Error&#039;,&#039;Error starting transaction ~n~r&#039; + sqlca.sqlerrtext)\n    \/\/ return logic here\nEND IF<\/pre>\n<p>After datawindow updates or imbedded sql calls.<\/p>\n<pre name=\"code\" class=\"VB\">\/\/ update\/insert\/delete check\nIF sqlca.sqlcode &lt; 0 THEN\n    ls_msg = sqlca.sqlerrtext\n    sqlca.of_rollback()\n    messagebox(&#039;Database Error&#039;,&#039;Error inserting into table -&gt; partMaster. ~n~r&#039; + ls_msg)\n    \/\/return logic here\nEND IF<\/pre>\n<p>And finally committing the changes to the database.<\/p>\n<pre name=\"code\" class=\"VB\">\/\/ commit\nIF sqlca.of_commit( ) &lt; 0 THEN\n    ls_msg = sqlca.sqlerrtext\n    sqlca.of_rollback()\n    messagebox(&#039;Database Error&#039;,&#039;Error saving changes ~n~r&#039; + ls_msg)\n    \/\/returns here\nEnd IF<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Here is a relatively painless way to handle transaction processing in your Powerbuilder application. This code assumes the use of the PFC but could be adapted without too much trouble. This will work with the following database connections: ADO.NET ASE, SYC and SYJ Sybase Adaptive Server Enterprise DIR Sybase DirectConnect I10 Informix IN9 Informix JDB&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,10],"tags":[33,12,16],"_links":{"self":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/294"}],"collection":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/comments?post=294"}],"version-history":[{"count":9,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/294\/revisions"}],"predecessor-version":[{"id":1798,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/posts\/294\/revisions\/1798"}],"wp:attachment":[{"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/media?parent=294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/categories?post=294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anvil-of-time.com\/wp-json\/wp\/v2\/tags?post=294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}