PostgreSQL connection pool handling via vb.net - vb.net

For Example,
In my vb.net application i have created two forms called FormA and FormB.When completes the FormA 's load dbMonitor shows Connection is returned to pool. Pool has 4 connection(s) and in the case of Formb dbMonitor shows Connection is returned to pool. Pool has 5 connection(s).when i use two form at a time the total connections will be 9.
do i need to clear all connection after form's load, if yes which method is safe
sometimes facing max connection problems while using my application via network computers.
VB.NET code to open connection is below
i have created a module for the connection
Imports Devart.Data.PostgreSql
Module Myconnstrection
Public Myconnstr As New PgSqlConnection("Server=" & gstrServerName & ";Port=" & gstrPort & ";Database=" & gStrDBName & ";User ID=" & gstrUserName & ";Password=" & gPassword)
End Module
i use the MyConnstr in my forms load or where ever a connection to the database is needed
try
Dim adapter As PgSqlDataAdapter = New PgSqlDataAdapter(strSql,
MyConnstr) myconnstr.open()
'Do my job
catch
finally
myconnstr.close()
end try
Databsase : PostgreSQL 9.2
OS : windows

Related

System.AccessViolationException occurs with MS Access databases just over WiFi connection

I'm developing a desktop application for my company (it's just a prototype, actually) for bringing simple services to production department (tool and process instructions, presence records, product traceability, etc).
I'm using VB.net and wpf; some MS Access databases are the backend. It uses Access Database Engine 2016.
I have a simple function used to update database records, here's it:
Public Function UpdateDatabaseRecord(DatabaseNumber As Integer, tblName As String, SearchInColumn As String, SearchBy As String, UpdateColumn As String, UpdateTo As String) As Integer
Try
Using ServerConnection As New OleDbConnection(ConnectionSelector(DatabaseNumber))
Dim CommandString As String
If SearchInColumn <> "ID" Then
CommandString = "UPDATE [" & tblName & "] SET [" & UpdateColumn & "]=#UpdateColumn WHERE [" & SearchInColumn & "] = " & DQ & SearchBy & DQ
Else
CommandString = "UPDATE [" & tblName & "] SET [" & UpdateColumn & "]=#UpdateColumn WHERE [" & SearchInColumn & "] = " & SearchBy
End If
Dim CommandUpdate As New OleDbCommand(CommandString, ServerConnection) With {.CommandTimeout = 10000}
With CommandUpdate.Parameters
.AddWithValue("#UpdateColumn", UpdateTo)
End With
ServerConnection.Open()
CommandUpdate.ExecuteNonQuery()
ServerConnection.Close()
End Using
UpdateDatabaseRecord = 0
SetCentralTimeStamp(DatabaseNumber, tblName)
Catch ex As Exception
Msg(Reflection.MethodBase.GetCurrentMethod.Name & NewLine & ex.Message & NewLine & "Err. Number " & Err.Number, "Database Error", MessageBoxButton.OK, MessageBoxImage.Error)
UpdateDatabaseRecord = Err.Number
End Try
End Function
Sometimes the application uses this function in the main thread; sometimes it runs it from scheduled task (clocked by a forms.timer every two minutes). This tasks aren't obviously in the main thread, but the code has been used succesfully for a couple of months with computers directly connected to company network via LAN cable. Recently I tried my application on a laptop connected via wifi to the company network, and I get an exception that's crashing my app. I installed VS on that laptop to debug the code, and I found that an AccessViolationException is raised on line "CommandUpdate.ExecuteNonQuery".
I tried to google it but it seems that this exception shouldn't be raised from managed code.
The error occours only with laptop connected via wifi.
Also, another function reads data from the databases: sometimes I get the same error in it, in the line where the connection is being opened (connection.open).
What should I check?
Thanks in advance.
ps "ConnectionSelector" is a simple function which returns the appropriate ConnectionString based on database number.
EDIT 1 - The WiFi network is created plugging directly a LAN cable from the actual wired network, using a common wireless router. IP addresses are automatically assigned and the connection works, since the app is able to get data from databases.
I solved the problem myself and I'm posting here the solution I found: I hope it will help someone in the future.
I resolved simply enabling all OLEDB Services for the database connection. It looks like connection pooling really help stability and performance, especially when using a wifi network like I'm forced to do. If you want, Google "OLEDB Services" and look for enabling them all.

Is it possible to change internet connection (e.g. from WiFi to Cable) with VBA?

For reporting purposes, I'm importing data from various sources on the net into an Excel Workbook.
Problem is: while some of the stuff I want is on my company's private network (requiring cable connection), some of the URL/webservices I want to connect to are not allowed by my company's proxy (via cable connection).
Thus, I have to use another connection without proxy (via WiFi) to get those to work.
This WiFi connection is always active on my computer, but it requires me to manually unplug the cable for half of my imports and to plug it back to access files on my company's network for the other half...
I wonder if there is a way with VBA to tell the computer to use cable / WiFi according to what I need.
I am working on a Windows XP Pro computer with Excel 2010/VBA. Please help!
Found Two ways to enable or disable i.e change internet adapter connection from VBA:
'adjust these according to your need i.e change adapter name, change enabled or disabled parameter, change path, change file name etc. VBS approach is long but gives more control. Bat approach is short but limited IMO
1 Using vbs Source link :
'file name: asdf.vbs
'Get and disable all physical wired adapters (AdapterTypeID=0) (Ethernet 802.3)
'Wscript.Echo "test"
Set wmi = GetObject("winmgmts:root\CIMV2")
Set adapters = wmi.ExecQuery("Select * from Win32_NetworkAdapter where _
AdapterTypeId=0 AND NetConnectionID IS NOT NULL",,48)
For Each adapter in adapters
With adapter
WScript.Echo "available: " & .Availability & " enabled: " & .NetEnabled & " netconStatus: " & .NetConnectionStatus & " status: " & .Status & " netconnID: " & .NetConnectionID & " adType: " & .AdapterType
'adapter.disable()
'adapter.enable()
End With
Next
' Get and disable all physical wireless adapters (AdapterTypeID=9) (wireless)
2 Using bat Ref link1 and Ref link2 :
'file name: switch_lan6.bat
#echo off
start /MIN cmd.exe /c "netsh interface set interface name="Local Area Connection 6" admin=disabled"
Running these inside excel vba:
Shell "wscript ""C:\Users\USER\Desktop\asdf.vbs""", vbNormalFocus
or,
Call Shell(ThisWorkbook.Path & "\switch_lan6.bat", 0)

MS Access VBA: Using workspace.OpenDatabase to connect to an unavailable SQL server via an ODBC connection - elegant recovery?

In an application that uses a MS Access form as a front-end to some SQL databases, I use DBEngine.CreateWorkspace to get a workspace, then workspace.OpenDatabase to connect to my remote SQL server via a defined ODBC System DSN. This all works quite nicely, until someone disconnects the remote SQL machine from the network, or shuts it down, or something else similarly ridiculous. (Note: I know there's a lot ridiculous about this setup, but unfortunately it's an inevitability at this point)
My question is:
Is there a way to elegantly deal with the timeout and subsequent 'SQL Server does not exist or access denied' error messages that come up, within the VBA code? workspace.OpenDatabase throws an error that I can catch and deal with, but not before two popups come up and stop my VBA code until an operator clicks OK.
DoCmd.SetWarnings False doesn't affect it as the error popups are not actually coming from Access itself - I think they're from the underlying ODBC process or the Jet Engine that drives it.
Any ideas?
A good solution can be found here:
ACC2000: How to Trap ODBC Logon Error Messages
http://support.microsoft.com/kb/210319
The above is from Access 2000 and is 14 years old, but as such it still works fine today. The other possible advantage is you don’t have to adopt and introduce ADO into your application. For applications that already use or have ADO, then no big deal, but if your application sticks to one data object model, then you not have to potentially introduce ADO.
The other BIG bonus of the above is this effectively logs you into the database and thus you avoid having user name and passwords in the linked tables. This means you can have different users and logons, and NOT have to re-link or embed the user name or password in your linked tables.
This wonderful trick and result of the above connection trick is outlined here:
Power Tip: Improve the security of database connections
http://blogs.office.com/b/microsoft-access/archive/2011/04/08/power-tip-improve-the-security-of-database-connections.aspx
I eventually found something that works by searching 'Suppress ODBC connection failure warnings'.
Courtesy of Trevor Best from http://bytes.com/topic/access/answers/201502-how-suppress-odbc-connection-dialog
Some code that uses ADO to make the database connection in a way that allows VBA error trapping to catch the error before the system throws any popups at you.
Function CanOpenSQLDbLB(pstrServer As String, pstrDb As String, pstrUser
As String, pstrPassword As String, Optional pfReportError As Boolean =
True) As Boolean
On Error GoTo CanOpenSQLDbLB_Err
Dim objConn As Object
Dim strConn As String
Dim strError As String, lngErr As Long
Const cstrSQLErr = "[Microsoft][ODBC SQL Server Driver][SQL Server]"
Set objConn = CreateObject("ADODB.Connection")
strConn = strConn & "DRIVER=SQL Server"
strConn = strConn & ";SERVER=" & pstrServer
strConn = strConn & ";APP=" & Application.Name
strConn = strConn & ";WSID=AWorkstation"
strConn = strConn & ";DATABASE=" & pstrDb
objConn.Open strConn, pstrUser, pstrPassword
CanOpenSQLDbLB = True
CanOpenSQLDbLB_Exit:
On Error Resume Next
objConn.Close
Set objConn = Nothing
Exit Function
CanOpenSQLDbLB_Err:
lngErr = Err.Number
strError = Err.Description
If InStr(1, strError, cstrSQLErr) Then
strError = "Error reported by server" & vbCr & vbCr &
Replace(strError, cstrSQLErr, "")
End If
Select Case lngErr
Case Else
If pfReportError Then
MsgBox strError, 16, "Error #" & Err & " Attempting to
open server database"
End If
End Select
Resume CanOpenSQLDbLB_Exit
End Function

Closing DbConnection Created by Function

Perhaps this is the complete wrong way of doing things, and if so could you perhaps point me in the correct (elegant) way. :)
I have a module in my vb.net project. The module deals with db connections. The idea is for other modules to make use of this module when connections need to be created.
For each database type I have function that opens the db connection. As an example I have this function that opens an oracle connection.
Friend Function OracleConnection(ByVal HostAddress As String, ByVal PortNumber As String, ByVal DBName As String, ByVal UserId As String, ByVal Password As String) As OracleConnection
Try
OracleConnection = New OracleConnection("Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" & HostAddress & ")(PORT=" & PortNumber & "))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=" & DBName & ")(FAILOVER_MODE=(TYPE=select)(METHOD=BASIC)(RETRIES=180)(DELAY=5))));User Id=" & UserId & ";Password=" & Password & ";")
OracleConnection.Open()
OracleConnection = OracleConnection
Catch ex As OracleException
MsgBox(ex.Message, MsgBoxStyle.Critical)
OracleConnection = Nothing
End Try
Return OracleConnection
End Function
Creating the connetion seems to work fine. The problem I have is that I am now not sure how to close the connection that got created by this function.
Option 1
You should always close OracleConnection objects by calling Close or Dispose, or by using the OracleConnection object within a Using statement.
Otherwise, the garbage collection might not free them immediately. Such delays can cause errors if the maximum number of connections is reached while a number of connections are waiting to be deleted by the garbage collector.
By contrast, closing the connections by calling Close uses native resources more efficiently, enhancing scalability and improving overall application performance. To ensure that connections are always closed, open the connection inside of a Using block.
Public Sub InsertRow(ByVal connectionString As String)
Dim queryString As String = "INSERT INTO Dept (DeptNo, Dname, Loc) values (50, 'TECHNOLOGY', 'DENVER')"
Using connection As New OracleConnection(connectionString)
Dim command As New OracleCommand(queryString)
command.Connection = connection
Try
connection.Open()
command.ExecuteNonQuery()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
End Sub
For more information, visit MSDN.
Option 2
Take a look at Oracle's recommended best practices:
http://www.oracle.com/technetwork/topics/dotnet/ow2011-bp-performance-deploy-dotnet-518050.pdf
You automatically get a connection pool when you create an OracleConnection. For most middle tier applications you will want to take advantage of that. You will also want to tune your pool for a realistic workload by turning on Performance Counters in the registry.
Please see the ODP.NET online help for details on connection pooling. Pool settings are added to the connection string.
Another issue people run into a lot with OracleConnections is that the garbage collector does not realize how truly resource intensive they are and does not clean them up promptly. This is compounded by the fact that ODP.NET is not fully managed and so some resources are hidden from the garbage collector.
Hence the best practice is to Close() AND Dispose() all Oracle ODP.NET objects (including OracleConnection) to force them to be cleaned up.
Credits go to Christian Shay this answer.

Can't connect to database, error 80040e21. Impossible to debug

I have a simple file that tries to connect to a database-
<%
Set RSDiscounts = Server.CreateObject("ADODB.Recordset")
RSDiscounts.ActiveConnection = "Data Source=serverName;Initial Catalog=dbName.dbo;Integrated Security=True"
%>
When I run it, I get-
error '80040e21'
/filename.asp, line 3
Searching for the error code doesn't help. My best guess is that something is specified in the connection string that shouldn't be there. But I used Visual Studio to create the string, and that connects to the database fine.
Is there any way I can figure out what's wrong? This seems like it's impossible to debug.
I think the problem is with your connection string - the string you have there is for ADO.Net but I don't believe that will work with ADODB.
Try a connection string like this:
Driver={SQL Native Client};Server=myServerName\theInstanceName;Database=myDataBase; Trusted_Connection=Yes
Or this is a connection string from one of my old projects with ADODB (from asp classic)
Provider=SQLOLEDB.1;Initial Catalog=databaseName;Data Source=serverName;Trusted Connection=Yes
That may not be 100% right, but you can find more details of all the connection strings you could want at the excellent ConnectionStrings.com.
From the library I wrote :
function SqlServerConnectionString( byval psDataSource, byval psCatalog, byval psUid, byval psPw)
'______________________________________________________________________________
'
' 'Sql Server Connection String'
'______________________________________________________________________________
dim x
x = "Provider=MSDASQL.1;Persist Security Info=False;User ID=" & psUid & ";Data Source=" & psDataSource & ";Initial Catalog=" & psCatalog
if psPw <> "" then
x = x & ";pwd=" & psPw
end if
SqlServerConnectionString = x
end function
I have similar routines for Firebird, Odbc and Access.
The problem will be you are trying to connect to the database using the user which is running the script. If this is running in IIS it will be something like USR_.
2 alternatives.
Give this user access to the database (I wouldn't do this one).
Create a SQL user and connect via this.
PROVIDER=SQLOLEDB;Data Source=serverName;Initial Catalog=dbName.dbo;USER ID=WebUser;PASSWORD=WebUserPassword;