Closed olafklinke closed 3 years ago
Update: Executing the same SQL statements using isql succeeds. Thus it is most likely a persistent-odbc or persistent issue. How can I find out which is the culprit?
Hi Olaf,
I've attached the code and output below, that tries to emulate your setup. It does run successfully, but I am running this on Windows.
If I explicitly call connClose at the end, then I do get the same error as here:
test.EXE: SqlError {seState = "[\"25000\"]", seNativeError = -1, seErrorMsg = "freeDbcIfNotAlready/SQLDisconnect: [\"0: [Microsoft][ODBC Driver 17 for SQL Server]Invalid transaction state\"]"}
Is this also what you are seeing?
Best, Grant
Thanks for investigating. Two differences: My code did not have the (deprecated) mkDeleteCascade sqlSettings
but that makes no difference. Second difference is I did not use runSqlConn
which makes me wonder whether we're talking about the same persistent
package major versions, because your example does not type check in my project. The type of the generated migrateAll
is ReaderT SqlBackend m ()
while in your code it seems to be Migration m -> m ()
which was changed from persistent-1.3.3 to persistent-2.0.0. Would you mind testing against persistent >= 2.0.0 again? I'm using the latest persistent-odbc-0.2.1.1 against persistent-2.10.5.3 (due to the constraint persistent < 2.11)
So the example I gave ran correctly with the stack.yaml overrides below. Can you send me a code snippet of what you actually used instead of runSqlConn so I can see where things are going wrong?
resolver: lts-17.0 packages:
stack ls dependencies ... persistent 2.10.5.3 persistent-odbc 0.2.1.1 persistent-template 2.8.2.3 ...
:t migrateAll migrateAll :: Migration
:i Migration type Migration :: * type Migration = Control.Monad.Trans.Writer.Lazy.WriterT [Text] (Control.Monad.Trans.Writer.Lazy.WriterT CautiousMigration (Control.Monad.Trans.Reader.ReaderT SqlBackend IO)) () -- Defined in ‘persistent-2.10.5.3:Database.Persist.Sql.Types’
Aha, I found the culprit. I defined my server
myserverType :: DBType
myserverType = MSSQL {mssql2012 = True}
myserver :: ConnectionString
myserver = undefined -- some real connection string"
Then I defined a shortcut
with_myserver :: (MonadUnliftIO m, MonadLogger m) => ReaderT SqlBackend m a -> m a
with_myserver = withODBCConn (Just myserverType) myserver . runReaderT
Note the runReaderT
at the end, which has the same type as runSqlConn
. I assumed that the latter is just a specialized form of the former, but apparently it is not. Looking at the source it is defined as
runSqlConn r conn = with (acquireSqlConn conn) $ runReaderT r
The call in Main looks then like this:
(runResourceT.runStderrLoggingT.with_myserver) (printMigration migrateAll)
If I replace runReaderT
with runSqlConn
the disconnect error disappears. What threw me off course was that the error message said something about disconnect, where the absence of acquireSqlConn
probably means there was no connection to disconnect at all. Thanks anyways for your help!
To reproduce: Pristine MS SQL server 2012. Installed the driver on Debian using
apt-get install msodbcsql17
Upon running either printMigration or runMigration, the commands seem to execute allright but the disconnect produces an error:
A web search suggests that after the last command the SQL driver implicitly starts another transaction which gets in the way of the disconnect. Putting SQL_AUTOCOMMIT_OFF in the connection string does not help.
The migration to run: