MTS and Python for NT

How to use python w/MTS on NT.


MTS represents microsoft's attempt to simplify computing for a distributed system. Where COM is all about identity, MTS manages state. It introduces new ideas and you'll find corresponding terminology like: object and state context, activity, causality. It also represents a push towards declarative programming -- where you declare how a class can exist and the operating system provides the services to handle that (instead of you having to deal with it). Windows 2000 offers a further set of refinements, though what's documented here will hopefully be backward compatible.


In this example, we'll specifically deal with a simple case that can show the transaction monitor in use. We have an active server page (using python of course) making calls to a python MTS component. The component then makes simple use of ObjectContext interfaces and decides whether or not the transaction is a success or failure.


To insert a python COM object into MTS, you want to register your COM object,setup an MTS package, and then add the python component to the package as a component that is already registered. After it is added, do not then register the component using python, as it will overwrite the changes MTS did. To create a package, open up the Transaction Server Explorer from the Option Pack, go to My Computer -> Packages Installed, right click and select new and create an empty package. From there you can call the package whatever you want and let it run as whomever. Then open up the package you created, right click on Components, select New Component, and finally select Import components that are already registered, from which you highlight your python component it provides in the list. You can also right click on Roles in your package to create a role you can put users or groups in. The last thing you need to do is right-click on your component in the package, select properties, and finally transaction. Then select the radio button next to: 'Requires a transaction'.


As stated before, this example is interested in ObjectContext. The ObjectContext interface is like a friend doing things on your behalf. You declare what you want, and it helps you with that, always acting as a buffer between you and the outside world. Many methods are available from this interface: CreateInstance, SetComplete, SetAbort, EnableCommit, DisableCommit, IsInTransaction, IsCallerInRole, etc.


In this example we will deal with: SetComplete and SetAbort, and IsCallerInRole. Invoking SetComplete will tell MTS that the object is done and it can go ahead and commit. In contrast, SetAbort means the object is done but for whatever the transaction must roll back. IsCallerInRole determines whether or not the client calling the object is in the role you created that has lists of users or groups.

Example

In python you setup the ObjectContext object in the following manner:

mtsobj = win32com.client.Dispatch("MTXAS.AppServer.1")

mts=mtsobj.GetObjectContext()

and can then make calls like:

if mts.IsCallerInRole('bedrock'):

	do_this()



<nl>Below is the active server page and python object that you can

watch at work using "Transaction Statistics" in the Transaction Server

Explorer. Anything but wilma and betty will cause the aborted list to

increment. If wila or betty are supplied from the ASP, you notice

Committed increasing.

Here is an extremely simple python active server page that calls the mts object:

<SCRIPT Language="Python" RunAt="Server">



import win32com

find_pebbles = win32com.client.dynamic.Dispatch("mts1")



a=find_pebbles('wilma')

Response.Write(a)



</SCRIPT>

Here is the mts COM object:

from win32com.server.exception import COMException

import win32com.server.util

import win32com.client.dynamic



#to generate guids use:

#import pythoncom

#print pythoncom.CreateGuid()



class Mts:

	# COM attributes.

	_reg_clsid_ = '{3D094770-B73E-11D3-99FC-00902776D585}'

		       #guid for your class in registry

	_reg_desc_ = "test mts functions"

	_reg_progid_ = "mts1" #The progid for this class

	_reg_class_spec_ = "mts_test.Mts"

			   #tells Python how to create the object: filename.class

	_public_methods_ = ['getkid' ]  #names of callable methods



	def __init__(self):

		pass



	def getkid(self, person):



		mtsobj = win32com.client.Dispatch("MTXAS.AppServer.1")

		mts=mtsobj.GetObjectContext()



		if mts is None:

			#com obj -- no mts

			result='error: mts not available'

		else:

			#mts is available

			#first check if they are in the right role

			if mts.IsCallerInRole('bedrock'):

				moms={'wilma':'bambam','betty':'pebbles'}

				person=str(person) #convert from unicode to string

				if moms.has_key(person):

					mts.SetComplete()

					result=moms[person]

				else:

					result='not in bedrock'

					mts.SetAbort()

			else:

				result='sorry can't let you know'

		return result



if __name__=='__main__':

	import win32com.server.register

	win32com.server.register.UseCommandLine(Mts)

Have a great time with programming with python!

John Nielsen   nielsenjf@my-deja.com