# Begin Transaction, problem with tx number java.util.map

**URL:** <https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [May 22, 2025, 8:51pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598 "2025-05-22T20:51:45Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 22, 2025, 8:51pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/1 "2025-05-22T20:51:45Z")

</div>

Hey all,

I am running a script from a button event, that sends a message to the root container, which runs a named query, and inserts a few values into the DB.  
I am trying to test the `system.db.beginNamedQueryTransaction` because I am trying to run multiple update queries back-to-back in a new project, but for some reason I only get a few updates (out of 27) to run successfully.  
In this test, this is the query:

```python
INSERT INTO [dbo].[Table_3] ([F1], [F2], [F3])
VALUES (:p_1, :p_2, :p_3 )

```

This is the message handler: (`test01')

```python
def onMessageReceived(self, payload):
	# implement your handler here
	query = 'Coater/Test01'
	p1 = self.getChild("NumericEntryField").props.value
	p2 = self.getChild("NumericEntryField_0").props.value
	p3 = self.getChild("TextField").props.text
	params = {'p_1':p1, 'p_2':p2, 'p_3':p3}
	proj = 'Sandbox_Sample'
	db = 'IGNSVR_Dev'
	tx = ''
	
	tx = system.db.beginNamedQueryTransaction(proj, db, 2)
	system.db.runNamedQuery(query, params, tx)
	system.db.commitTransaction(tx)

(I removed the closeTransaction to see if anything would change...)

```

This is the button event script:

```python
def runAction(self, event):
	msg = 'test01'
	payload = {}
	system.perspective.sendMessage(msg, payload)

```

This is the gist of the error:

```python
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File "", line 23, in onMessageReceived at ... 
java.lang.ClassCastException: java.lang.ClassCastException: 
Cannot coerce value '90da8353-ce17-42a0-852e-65506aacc7d2' into type: interface java.util.Map

```

I've read a few other threads and the docs and it appears the args for Perspective scope are correct.  
Any ideas?

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [May 22, 2025, 8:56pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/2 "2025-05-22T20:56:53Z")

</div>

> [@mdemaris](#):
>
> ` type: interface java.util.Map`

Looks like in some cases the tx is being passed to the `params` argument of the `runNamedQuery` function.

```python
system.db.runNamedQuery(query, params, tx)

```

Needs project name at the front. If this is in perspective it runs in gatetway-esc scope, despite what the manual says.

I made a helper function to automatically add project name at the front based on the executed scope. I use this across the board in perspective projects, handlers and otherwise. Some of my use cases match yours exactly (message -\> handler -\> transaction), though all my handlers are 1 line calls to a script library function.

```python
def runContextualNamedQuery(path, params=None, tx=None, getKey=False):
	""" """
	if shared.util.getExecutionScope() in ("P", "G"):
		return system.db.runNamedQuery(system.util.getProjectName(), path, params, tx, getKey)
	else:
		return system.db.runNamedQuery(path, params, tx, getKey)

```

```python
from com.inductiveautomation.ignition.common.model import ApplicationScope

def getExecutionScope():
	""" """
	scope = ApplicationScope.getGlobalScope()
	if ApplicationScope.isClient(scope):
		return "C"

	if ApplicationScope.isDesigner(scope):
		return "D"

	if ApplicationScope.isGateway(scope):
		if "perspective" in dir(system):
			return "P"

		return "G"

	return "UNK"

```

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 22, 2025, 9:32pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/3 "2025-05-22T21:32:43Z")

</div>

> [@ryan.white](#):
>
> `shared.util.getExecutionScope() `

`shared.util` is a Project Library package?

This works well! Thank you Ryan!

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [May 22, 2025, 9:36pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/4 "2025-05-22T21:36:26Z")

</div>

> [@mdemaris](#):
>
> Project Library package?

Correct, its in the project at the top of our inheritance stack. We've also put stuff like pturmel's `later.py`, `xml.py` and `queueUtil.py` in there.

Edit, looks like this issue has been around a while? Found this:

> [@\[IGN-3829\] Error executing system.db.commitTransaction](https://forum.inductiveautomation.com/t/ign-3829-error-executing-system-db-committransaction/49595/27):
>
> I had a similar problem when I was trying to set up an all or nothing write to our DB. What fixed it for me was the first query in the transaction (after getting the transaction ID) needed to have the project argument filled. Subsequent named query calls do not need that parameter filled. This worked: txID = system.db.beginNamedQueryTransaction(project="project1", database="database1") try: system.db.runNamedQuery(project="project1", path="query1", params=params1, tx=txID) #do some stu…

Also, if you are interested, a transaction decorator that automatically catches errors:

> [@Script Benchmarking with Decorators Example](https://forum.inductiveautomation.com/t/script-benchmarking-with-decorators-example/63507/5):
>
> I made something similar to what you are aiming for but its also made for managing database transactions and errors in a standard way by creating a Response object that then I inspect after. import functools import timeit import traceback from forms2.structs import Response import java.lang.Throwable class handleTransaction(object): def \_\_init\_\_(self, logger): self.logger = logger def \_\_call\_\_(self, inner\_func): """ We do 'tx' not in kwargs a few times here. If a fucntion has tx=None…

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 22, 2025, 9:59pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/5 "2025-05-22T21:59:09Z")

</div>

> [@ryan.white](#):
>
> `if "perspective" in dir(system):`

This will always be true (in gateway scope, if you have the Perspective module installed) - this won't catch scenarios where you're not in a Perspective launched context but elsewhere on the gateway (e.g. a tag event script). See @nminchin's similar looking code here:

> [@Get current scope in scripting](https://forum.inductiveautomation.com/t/get-current-scope-in-scripting/55686/18):
>
> There are a number of topics about this, with this being the only topic that works to distinguish between gateway and perspective slight_smile thanks @PGriffith and @hunterdg I've incorporated this into @Kyle_Chase 's script from [this topic](https://forum.inductiveautomation.com/t/best-methods-for-checking-script-scope/30201/2): from com.inductiveautomation.ignition.common.model import ApplicationScope try: from com.inductiveautomation.ignition.gateway import IgnitionGateway isGateway = True except ImportError: isGateway = False def getScope(): scope = ApplicationScope.getG…

I'll also mention for posterity here that in 8.3 we introduced new named query scripting functions to address this fundamental inconsistency.

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [May 22, 2025, 10:03pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/6 "2025-05-22T22:03:24Z")

</div>

> [@paul-griffith](#):
>
> This will always be true

Huh, guess I've been lucky enough with my usage I haven't smacked into this. Will update this immediately.

Any insight as to why the named query call is expecting the project name, despite being called in a perspective context? This appears to only happen after starting a transaction in a perspective scope.

---

<div class="post-metadata">

**Author:** ![mdemaris](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mdemaris/32/54639_2.png) [@mdemaris](https://forum.inductiveautomation.com/u/mdemaris)\
**Post date:** [May 22, 2025, 11:02pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/7 "2025-05-22T23:02:57Z")

</div>

I don't know if this makes any difference, but I tried `IsolationLevel` 8 and things weren't working very well, with 27 update queries in queue, but with a level 2, everything seems to work fine so far. I also changed the helper function as Paul pointed out in the other thread.

EDIT:  
And, I'm running them like this:

```python
		try:
			runContextualNamedQuery(query, params, txNumber1)
		except Throwable as t:
			system.db.rollbackTransaction(txNumber1)
		else:
			system.db.commitTransaction(txNumber1)
		finally:
			system.db.closeTransaction(txNumber1)
		
		sleep(0.5)

```

I don't know if the `sleep` is necessary, but I seem to recall an issue with running queries without a slight pause. This might not make a difference when using transactions, though. Have yet to test it out.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 22, 2025, 11:09pm UTC](https://forum.inductiveautomation.com/t/begin-transaction-problem-with-tx-number-java-util-map/106598/8 "2025-05-22T23:09:40Z")

</div>

> [@ryan.white](#):
>
> This appears to only happen after starting a transaction in a perspective scope.

Not sure. I would've thought that providing a transaction entered some different block of code early on, but the check to load the contextual project name happens right at the top of the `runNamedQuery` block.
