1. Sivaprakash BKR
  2. PowerBuilder
  3. Wednesday, 27 December 2023 09:04 AM UTC

Hello,

Using PB 2022 R2, b 2819, SQLite 3 [ unsupported database ].

While updating multiple tables after starting database transactions, control goes into infinite loop, on the line dw_3.Update(True, False)

1.  No issues when updating single table.

2.  No issue when updating multiple tables without starting database transaction.

3  Issue is when we update multiple tables after starting database transaction. 

Couldn't identify the pattern when and on what condition this issue arises.  

We have a window which updates three tables and it works fine.

Another window which updates 7 tables, is having this issue.   It could update 2 tables without any issue.  Adding any other table [ dw / ds ] to the update event makes the control goes into infinite loop.  

Have anyone used SQLite?  Any such issues found?  Any workaround?

Happiness Always
BKR Sivaprakash

 

Miguel Leeuwe Accepted Answer Pending Moderation
  1. Friday, 29 December 2023 08:47 AM UTC
  2. PowerBuilder
  3. # 1

Hi BKR,

Not sure if I haven't read everything very well, but how do things get into an infinite loop? I don't see any recursive or repeating process. Have you tried to add "TRACE " in front of your sqlca.dbms setting so it generates a log file?

regards and happy holidays.

Comment
  1. Sivaprakash BKR
  2. Saturday, 30 December 2023 08:33 AM UTC
Thanks Miguel, Chris.

As Chris says, PB app might be waiting for SQLite to finish its work, which never gets completed. Let me check with 'Trace' Miguel.
  1. Helpful
  1. Miguel Leeuwe
  2. Saturday, 30 December 2023 08:52 AM UTC
Ah okay, so not a "loop", just anything that takes a very long time or is locked.

What I would recommend is - if possible - "somehow" disconnect your connection with the DB when the process never seems to finish, so that you can see what the last SQL statement was in your trace log. Maybe a tool like DBeaver could help out to see what SQL is running. I'm not familiar with SQLite, so I don't know what tools are available to trace in different ways.
  1. Helpful
  1. Sivaprakash BKR
  2. Saturday, 30 December 2023 10:32 AM UTC
Miguel,

The last SQL Statement was an insert statement [ sqlpreview event & debugger ]. When I stepin in debugger, the last statement executed was dw_2.update which fires sqlpreview event that displays the sql statement.

It works well when I comment out the autocommit statement.

  1. Helpful
There are no comments made yet.
Sivaprakash BKR Accepted Answer Pending Moderation
  1. Thursday, 28 December 2023 06:39 AM UTC
  2. PowerBuilder
  3. # 2

Thanks Chris, Armeen.

More updates:

1.  SQLite database is used in a single user mode.  Only one connection is made from Powerbuilder.  Hope PB doesn't make any hidden connections.
2.  Database is in local drive only and NOT in any network drive.
3.  Connection using DSN-Less connection

My connection parameters are

SQLCA.DBMS="ODBC"
SQLCA.DBParm="ConnectString='Driver=SQLite3 ODBC Driver;Database=E:\PowerBuilder 2022\V6.0.0 (64 bit)\BaseCommon\Data\one.db;FKSupport=True;AttachAs=public'"
SQLCA.Lock="RC"

Save Event

SQLCA.AutoCommit = False
ll_rc = Event ue_saveprocess_update()
If ll_rc = 1 Then
	SQLCA.of_commit()
	Event ue_saveprocess_reset()
Else
	SQLCA.of_rollback()
	OpenWithParm(w_display_error, io_dberror_data)
End If
SQLCA.AutoCommit = True

Event ue_saveprocess_update

/* Event ue_saveprocess_update */

Long			ll_rc

ll_rc = dw_entry.Update(True, False)
If (ll_rc <> 1 And ib_dberror = False) Then		// For dbError = True, Error captured at DBError Event which should not be overwritten here
	PopulateError(999, "notused")
	io_dberror_data.of_set( "MessageType",   "Error")
	io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
	io_dberror_data.of_set( "Error Object",  Error.Object)
	io_dberror_data.of_set( "Error Event",   Error.objectevent)
	io_dberror_data.of_set( "Child Object",  is_child_object)
	io_dberror_data.of_set( "Error Message", 'Save Failed in Entry DW')
	Return ll_rc
ElseIf ib_dberror = True Then
	Return -1
End If

If is_tab_dw_update[1] = 'Y' Then
	ll_rc = tab_1.tabpage_1.dw_1.Update(True, False)
	If (ll_rc <> 1 And ib_dberror = False) Then
		PopulateError(999, "notused")
		io_dberror_data.of_set( "MessageType",   "Error")
		io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
		io_dberror_data.of_set( "Error Object",  Error.Object)
		io_dberror_data.of_set( "Error Event",   Error.objectevent)
		io_dberror_data.of_set( "Child Object",  is_child_object)
		io_dberror_data.of_set( "Error Message", 'Save Failed in Tabpage_1 DW_1')
		Return ll_rc
	ElseIf ib_dberror = True Then
		Return -1
	End If
End If

If is_tab_dw_update[2] = 'Y' Then
	ll_rc = tab_1.tabpage_2.dw_2.Update(True, False)
	If (ll_rc <> 1 And ib_dberror = False) Then
		PopulateError(999, "notused")
		io_dberror_data.of_set( "MessageType",   "Error")
		io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
		io_dberror_data.of_set( "Error Object",  Error.Object)
		io_dberror_data.of_set( "Error Event",   Error.objectevent)
		io_dberror_data.of_set( "Child Object",  is_child_object)
		io_dberror_data.of_set( "Error Message", 'Save Failed in Tabpage_2 DW_2')
		Return ll_rc
	ElseIf ib_dberror = True Then
		Return -1
	End If
End If

If is_tab_dw_update[3] = 'Y' Then
	ll_rc = tab_1.tabpage_3.dw_3.Update(True, False)
	If (ll_rc <> 1 And ib_dberror = False) Then
		PopulateError(999, "notused")
		io_dberror_data.of_set( "MessageType",   "Error")
		io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
		io_dberror_data.of_set( "Error Object",  Error.Object)
		io_dberror_data.of_set( "Error Event",   Error.objectevent)
		io_dberror_data.of_set( "Child Object",  is_child_object)
		io_dberror_data.of_set( "Error Message", 'Save Failed in Tabpage_3 DW_3')
		Return ll_rc
	ElseIf ib_dberror = True Then
		Return -1
	End If
End If

If is_tab_dw_update[4] = 'Y' Then
	ll_rc = tab_1.tabpage_4.dw_4.Update(True, False)
	If (ll_rc <> 1 And ib_dberror = False) Then
		PopulateError(999, "notused")
		io_dberror_data.of_set( "MessageType",   "Error")
		io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
		io_dberror_data.of_set( "Error Object",  Error.Object)
		io_dberror_data.of_set( "Error Event",   Error.objectevent)
		io_dberror_data.of_set( "Child Object",  is_child_object)
		io_dberror_data.of_set( "Error Message", 'Save Failed in Tabpage_4 DW_4')
		Return ll_rc
	ElseIf ib_dberror = True Then
		Return -1
	End If
End If

If is_tab_dw_update[5] = 'Y' Then
	ll_rc = tab_1.tabpage_5.dw_5.Update(True, False)
	If (ll_rc <> 1 And ib_dberror = False) Then
		PopulateError(999, "notused")
		io_dberror_data.of_set( "MessageType",   "Error")
		io_dberror_data.of_set( "Error Line",    String ( Error.Line ))
		io_dberror_data.of_set( "Error Object",  Error.Object)
		io_dberror_data.of_set( "Error Event",   Error.objectevent)
		io_dberror_data.of_set( "Child Object",  is_child_object)
		io_dberror_data.of_set( "Error Message", 'Save Failed in Tabpage_5 DW_5')
		Return ll_rc
	ElseIf ib_dberror = True Then
		Return -1
	End If
End If

Return 1

Control goes into infinite loop, when it updates the second dw/ds.   

If we run as such, the second update tab_1.tabpage_1.dw_1.update(True, False) goes into infinite loop.
If we comment out the first dw update, then the third update tab_1.tabpage_2.dw_2.update(True, False) goes into infinite loop.

Works well, if we comment out the begin transaction / commit / rollback statements

//SQLCA.AutoCommit = False
ll_rc = Event ue_saveprocess_update()
If ll_rc = 1 Then
	//SQLCA.of_commit()
	Event ue_saveprocess_reset()
Else
	//SQLCA.of_rollback()
	OpenWithParm(w_display_error, io_dberror_data)
End If
//SQLCA.AutoCommit = True

May be some issues is in the locking mechanism?  A file with -journal suffix is created when in the database file folder when db transactions are enabled.  

Things became more confusing:

Another window with 3 datawindows [ 3 different tables] gets updated without any issues with database transactions enabled.  Here also a file with -journal suffix is created, and it got deleted at the end of the transaction [ ie on Commit ].

Happiness Always
BKR Sivaprakash

 

Comment
There are no comments made yet.
Armeen Mazda @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 27 December 2023 17:45 PM UTC
  2. PowerBuilder
  3. # 3

Not sure if typical PB programming and DW usage jives well or not with how transaction management works in SQLite: https://www.sqlite.org/lang_transaction.html#:~:text=SQLite%20supports%20multiple%20simultaneous%20read,allows%20both%20reading%20and%20writing.

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Wednesday, 27 December 2023 14:55 PM UTC
  2. PowerBuilder
  3. # 4

Hi BKR;

  FWIW: I hope that your App is not doing its own "Begin/End Transaction" commands as PB does those for you in the background automatically.

Regards ... Chris 

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.