system.db.runPrepUpdate can't use database name in decorator?

I was recently tasked with switching our database structure and was looking forward to using my new architecture to change the values in a few locations to get everything working, however I ran into a snag. To ensure all queries run safely and rollback with consistent logic, I put together the below Safe Txn Decorator. However, if system.db.runPrepUpdate is run in the decorated function (func) it ignores the database field and goes straight to using the project default. I removed the Decorator from the source function and it worked without issue.

def _Dec_SafeTxn():
	def decorator(func):
		@wraps(func)
		def wrapper(self, *args, **kwargs):
			if not "txId" in kwargs or not kwargs["txId"]:
				txn = system.db.beginTransaction(self.database.name)
				isTxId = False
			else:
				txn = kwargs["txId"]
				isTxId = True
			
			del kwargs["txId"]
				
			try:
				out = func(self, *args, txId = txn, **kwargs)
				
				if isTxId:
					if self.testMode:
						system.db.rollbackTransaction(txn)
					else:
						system.db.commitTransaction(txn)
				
			except java.lang.Exception as e:
				if not isTxId:
					system.db.rollbackTransaction(txn)
				
				if e.getCause():
					message = e.getCause().getMessage()
				else:
					message = str(e)
					
				Logger(loggerName = 'Safe Txn Logger').error(message)
				raise
			except Exception as e:
				if not isTxId:
					system.db.rollbackTransaction(txn)
				
				LoggerException(loggerName = 'Safe Txn Logger').error(e)
				raise
			finally:
				if not isTxId:
					system.db.closeTransaction(txn)
					
			return out
	
		return wrapper
	return decorator

This was inconvenient during testing and I can get by with changing the project Database, but want to know if this is a bug or I am doing something wrong?

To confirm, your issue is that something like this:


@_Dec_SafeTxn
def doSomethingWithTheDb():
    system.db.runPrepUpdate(...)

Doesn't use the transaction in the inner call to runPrepUpdate?

Yes, though @_Dec_SafeTxn() needs the parentheses. The issue is that system.db.runPrepUpdate(qry, args, database = “DatabaseConnection”) in this case isn’t using “DatabaseConnection”, it uses the project default database instead.

In gateway or client scope?

Same effect in both the script console and through a perspective event script. Didn’t check carefully, but I wasn’t getting writes from gateway timer events either.

1 Like

Thanks. I'll throw it on my list to investigate, but with the holidays coming up, not sure when that'll actually happen.

I'd also recommend making an official report to support to keep me honest and make sure you get informed if/when we do find a bug and get it fixed.

1 Like