1313
1414# Utilities.
1515from dls_utilpack .callsign import callsign
16+ from dls_utilpack .describe import describe
1617from dls_utilpack .explain import explain
1718from dls_utilpack .isodatetime import isodatetime_filename
1819from dls_utilpack .require import require
@@ -70,6 +71,66 @@ def __init__(self, specification, database_definition_object):
7071 # Last undo position.
7172 self .__last_restore = 0
7273
74+ # ----------------------------------------------------------------------------------------
75+ async def __get_isolation_level (self ):
76+ # Read the current isolation level
77+ cursor = await self .__connection .execute ("PRAGMA isolation_level" )
78+ result = await cursor .fetchone ()
79+
80+ logger .debug (describe ("result" , result ))
81+
82+ if result is None :
83+ isolation_level = ""
84+ else :
85+ isolation_level = result [0 ]
86+
87+ return isolation_level
88+
89+ # ----------------------------------------------------------------------------------------
90+ async def __set_isolation_level (self ):
91+ """
92+ Set the isolation level on the connection.
93+
94+ Set isolation level such that all statements which are not already in an explicit transaction
95+ are autocommitted immediately and visible on other connections.
96+ This might be less efficient? But it's nice when monitoring a sqlite file with a management tool.
97+ TODO: Consider the ramifications of setting aiosqlite isolation_level to None.
98+ """
99+
100+ # Possible values are None, '' (default), DEFERRED, and EXCLUSIVE.
101+ # Default if not mentioned in the configuration is None.
102+ configured_isolation_level = self .__type_specific_tbd .get ("isolation_level" , "" )
103+ previous_isolation_level = await self .__get_isolation_level ()
104+
105+ logger .debug (describe ("previous_isolation_level" , previous_isolation_level ))
106+
107+ if configured_isolation_level == previous_isolation_level :
108+ logger .debug (
109+ f"isolation_level is already the configured '{ configured_isolation_level } '"
110+ )
111+ else :
112+ logger .debug (
113+ f"isolation_level is needs to be set from '{ previous_isolation_level } ' to '{ configured_isolation_level } '"
114+ )
115+
116+ if configured_isolation_level is None :
117+ await self .execute ("PRAGMA isolation_level =" )
118+ else :
119+ await self .execute (
120+ f"PRAGMA isolation_level = { configured_isolation_level } "
121+ )
122+ await self .commit ()
123+
124+ readback_isolation_level = await self .__get_isolation_level ()
125+
126+ if readback_isolation_level != configured_isolation_level :
127+ raise RuntimeError (
128+ f"readback isolation level '{ readback_isolation_level } ' does not match '{ configured_isolation_level } ' as was set"
129+ )
130+ logger .debug (
131+ f"isolation_level is now set from '{ previous_isolation_level } ' to '{ readback_isolation_level } '"
132+ )
133+
73134 # ----------------------------------------------------------------------------------------
74135 async def connect (self , should_drop_database = False ):
75136 """
@@ -96,8 +157,11 @@ async def connect(self, should_drop_database=False):
96157 # This might be less efficient? But it's nice when monitoring a sqlite file with a management tool.
97158 # TODO: Consider the ramifications of setting aiosqlite isolation_level to None.
98159 # Possible values are None, '' (default), DEFERRED, and EXCLUSIVE.
160+ logger .debug (
161+ f"isolation_level was set to '{ self .__connection .isolation_level } '"
162+ )
99163 isolation_level = self .__type_specific_tbd .get ("isolation_level" , None )
100- self .__connection .isolation_level = isolation_level
164+ # self.__connection.isolation_level = isolation_level
101165 logger .debug (
102166 f"isolation_level is now set to '{ self .__connection .isolation_level } '"
103167 )
@@ -233,6 +297,9 @@ async def begin(self):
233297 Begin transaction.
234298 """
235299
300+ # Close off any transactions underway.
301+ await self .__connection .commit ()
302+
236303 await self .__connection .execute ("BEGIN" )
237304
238305 # ----------------------------------------------------------------------------------------
0 commit comments