5 Using COM Transactions

This chapter contains the following topics:

5.1 Understanding COM Interoperability Transactions

COM interoperability transactions include COM connector prepare, commit, and rollback functionality. The COM transaction interoperability solution supports these types of transactions:

  • Auto commit transactions

  • Manual commit transactions

A transaction can be started as auto commit or manual commit. In auto commit, JD Edwards EnterpriseOne automatically commits the transaction that has been started. If a transaction is started in manual commit, you have to explicitly call prepare and commit functionality for the transaction to be committed.

The COM connector also supports manual commit. Typically, a transaction is started in manual commit by calling BeginTransaction with the flag set to 1. Subsequent calls to prepare and commit commits the transaction. The COM connector prepare and commit does not support distributed transactions that involve transactions other than JD Edwards EnterpriseOne.

5.1.1 Outline for Calling Prepare and Commit

This table provides an outline for calling prepare and commit:

Function Description
Dim soeOWInterface As OneWorldInterface Declare the OneWorldInterface.
soeOWInterface.BeginTransaction (accessNumber, connector, txMode) Start the transaction in manual commit by calling begin transaction and setting the txMode to 1. 0 is for auto commit.
//execute all BSFNs like the

//enddoc and other BSFNs

After a call to Begin Transaction is made, do all the transactions that you want to enclose within this manual commit before calling prepare.
soeOWInterface.Prepare Call prepare when all of the transactions are done.
soeOWInterface.Commit

(or)

soeOWInterface.RollBack

Call Commit to commit the transaction

(or)

Rollback to roll back the transaction if an error occurs.


The default timeout value for a manual transaction is 5 minutes. If you do not commit the transaction within 5 minutes, the transaction context is freed and the transaction is rolled back. You can change the default timeout by setting the manual_timeout value in the [INTEROP] section of the jdeinterop.ini file. The value is in milliseconds.

5.1.2 COM+ Two-Phase Commit Transaction

The COM connector can participate in distributed transactions. The COM connector's ability to participate in distributed transactions enables any application that uses the COM connector to participate in the two-phase commit transaction. Applications that have the capability to participate in distributed transactions can also use the COM connector.

5.2 Setting Up the COM+ Environment

Typically, when you use COM+ for two-phase commit, you must set up the environment for these three computers:

  • COM connector

  • JD Edwards EnterpriseOne server

  • Database server

A distributed transaction coordinator (DTC) is expected to run on each of the machines. Before testing the COM+ two-phase commit, you must make sure that the DTCs on each machine are correctly configured and that the DTCs talk to each other.

This illustration shows the physical configuration:

Figure 5-1 COM+ Environment Configuration

Description of Figure 5-1 follows
Description of "Figure 5-1 COM+ Environment Configuration"

Note:

Typically, administrative rights are required for you to run the examples, which talk to DTCs on different machines. For more information about setting up DTC and various configurations, refer to the Microsoft documentation.

5.3 Running a COM+ Transactions

This section provides an overview of JD Edwards EnterpriseOne participating in a COM+ transaction and discusses how to:

  • Create a Transactional Object

  • Create a Transactional Client

5.3.1 Understanding COM+ Transactions

This code outline explains how to develop code for COM connector and JD Edwards EnterpriseOne participation in COM+ transactions:

Code Explanation
Dim ow As OneWorldTx Declare new OneWorldTx.
Set ow = New OneWorldTx

ow.Initialize laccessNumber, connRole

Initialize the transaction by passing the access number returned from a successful logon and the connector.
ow.BeginTransaction laccessNumber, connRole, 1 Start a transaction in Manual Commit.

1 Manual commit

0 Auto Commit

EditLine, EndDoc Do all the processing here like BeginDoc.
GetObjectContext().SetComplete

or

GetObjectContext().SetAbort

Use SetComplete to commit the transaction through DTC

or

use SetAbort to abort the transaction.


Note:

In COM+, an AutoCommit attribute exists that implicitly commits a transaction if no errors exist. This attribute is in the Component Services Administration tool. However, if an explicit call to SetAbort is made, the transaction aborts.

These code examples illustrate how to create a sales order entry transactional object (SOETxObject) and a sales order entry transactional client (SOETxClient). After you create the transactional object and transactional client, you can run the transactions. Use these steps to run a sales order entry transaction in COM+ where the COM connector and JD Edwards EnterpriseOne participate:

  1. Run the SOETxObject.

  2. Run the SOETxClient.

  3. Note the Sales Order Entry number that is displayed.

  4. When the message box appears for Commit or Abort, select the appropriate action.

  5. Verify in JD Edwards EnterpriseOne whether the sales order has been entered. The sales order should be entered only when committed.

5.3.2 Creating a Transactional Object (SOEProj.vbp)

This sample code shows how to create a SalesOrderEntry transactional object (SOETxObject => SOEClass2.cls).

Public Sub run()
On Error GoTo errorhandler
Dim ow As OneWorldTx

 Dim bhvr As IOneWorldBHVRCOM
  
 Dim conn As New Connector           '// COM Connector
 Dim connRole As IConnector2         '// Connector Interface with Roles

 Dim soeObject As JDESalesOrderEntry '// SalesOrderEntry
 Dim soeBeginDoc As D4200310H
 Dim soeEndDoc As D4200310G
 Dim soeEditLine As D4200310F
 Dim soeClearWF As D4200310I
 Dim s As String
 Dim d As New MathNumeric
 Dim mnQuanityOrdered As New MathNumeric
 Dim mnUnitPrice As New MathNumeric
 Dim response

 Dim laccessNunber As Long

 ' Name Information
 Dim strComputerName As String
 Dim lngNameLength As Long

 Const WRITE_FLAG = "2"

 Dim i As Boolean
 Set connRole = conn
 laccessNumber = connRole.Login("UserID", "PWD", "ENV", "ROLE")

 Set ow = New OneWorldTx

 ow.Initialize laccessNumber, connRole
 'oneworld transaction initialized to manual
 ow.BeginTransaction laccessNumber, connRole, 1

 Set bhvr = ow
 bhvr.szApplication = "COM+"
 Set soeObject = connRole.CreateBusinessObject("SalesOrderEntry.
JDESalesOrderEntry", laccessNumber) 
' please change the progid to correct progId
 Set soeBeginDoc = soeObject.CreateF4211FSBeginDocParameterset
 Set soeEditLine = soeObject.CreateF4211FSEditLineParameterset
 Set soeEndDoc = soeObject.CreateF4211FSEndDocParameterset
 Set soeClearWF = soeObject.CreateF4211ClearWorkFileParameterset

 ' Get computer name for use later
 strComputerName = Space(30)
 lngNameLength = 30
 p_ret = GetComputerName(strComputerName, lngNameLength)
 If p_ret <> 1 Then
   MsgBox (GetComputerName failed!)
   'End
 Else
   strComputerName = Mid(strComputerName, 1, lngNameLength)
 End If
 ' MsgBox (Create Biz Object Done!)

 '//////////////BEGIN DOC//////////////
 soeBeginDoc.Reset
 soeBeginDoc.cCMDocAction = "A"
 soeBeginDoc.cCMProcessEdits = "1"
 soeBeginDoc.cCMUpdateWriteToWF = WRITE_FLAG
 soeBeginDoc.szCMProgramID = "VB"
 soeBeginDoc.szCMVersion = "ZJDE0001"
 soeBeginDoc.szOrderCo = "00200"
 soeBeginDoc.szOrderType = "SO"
 szBUnit = "M30"
 soeBeginDoc.szBusinessUnit = Space(12 - Len(szBUnit)) + szBUnit
 d = Val("4242")
 soeBeginDoc.mnAddressNumber = d
 soeBeginDoc.mnShipToNo = d
 soeBeginDoc.jdOrderDate = Date
 soeBeginDoc.cMode = "F"
 soeBeginDoc.szUserID = "JDE"
 soeBeginDoc.cRetrieveOrderNo = "1"

 If strComputerName <> "" Then
     soeBeginDoc.szCMComputerID = strComputerName
 End If
 ' MsgBox ("Before F4211FSBeginDoc")
 soeObject.F4211FSBeginDoc soeBeginDoc, ow, connRole, laccessNumber

 MsgBox Round(soeBeginDoc.mnOrderNo, 0)

 '//////////EDIT LINE////////////
    
 soeEditLine.mnCMJobNo = soeBeginDoc.mnCMJobNumber
 orderNum = soeBeginDoc.mnOrderNo
 soeEditLine.mnOrderNo = soeBeginDoc.mnOrderNo
 soeEditLine.szBusinessUnit = soeBeginDoc.szBusinessUnit
 soeEditLine.szCMComputerID = soeBeginDoc.szCMComputerID
 soeEditLine.cCMWriteToWFFlag = WRITE_FLAG

 soeEditLine.szOrderType = soeBeginDoc.szOrderType
 ' Load items from UI into edit line structure
 soeEditLine.szItemNo = "1001"
 mnQuanlityOrdered = "2"
 soeEditLine.mnQtyOrdered = mnQuanityOrdered

 ' MsgBox ("Before F4211FSEditLine.")
 ' Call business function
 soeObject.F4211FSEditLine soeEditLine, ow, connRole, laccessNumber
 ' MsgBox ("After F4211FSEditLine.")
  
 '///////////////ENDDOC//////////////
 soeEndDoc.mnCMJobNo = soeBeginDoc.mnCMJobNumber
 soeEndDoc.mnSalesOrderNo = soeBeginDoc.mnOrderNo
 soeEndDoc.szOrderType = soeBeginDoc.szOrderType
 soeEndDoc.szCMComputerID = strComputerName
 soeEndDoc.cCMUseWorkFiles = WRITE_FLAG
 'Call business function
 
  'MsgBox ("Before F4211FSEndDoc.")
 soeObject.F4211FSEndDoc soeEndDoc, ow, connRole, laccessNumber
 'MsgBox ("After F4211FSEndDoc.")
 MsgBoxRes = MsgBox("Do you want to abort?", vbYesNo, "Transaction 
Decision")
 If MsgBoxRes = vbYes Then
   GetObjectContext.SetAbort
 Else
   GetObjectContext.SetComplete
   MsgBox ("Order Saved")
 End If
    
 '///////CLEAR WORK FILE////////////////

 soeClearWF.cClearDetailWF = WRITE_FLAG
 soeClearWF.cClearHeaderWF = WRITE_FLAG
 soeClearWF.mnJobNo = soeBeginDoc.mnCMJobNumber
 soeClearWF.szComputerID = strComputerName
 'Call business function
 'MsgBox ("Before F4211ClearWorkFile.")
 ow.BeginTransaction laccessNumber, connRole, 0
 soeObject.F4211ClearWorkFile soeClearWF, ow, connRole, laccessNumber
 'MsgBox ("After F4211ClearWorkFile.")
 Set soeObject = Nothing
 Set soeBeginDoc = Nothing
 Set soeEditLine = Nothing
 Set soeEndDoc = Nothing
 Set ow = Nothing
 connRole.Logoff (laccessNumber)
 Set connRole = Nothing

 Exit Sub

errorhandler:
 GetObjectContext().SetAbort
 connRole.Logoff (laccessNumber)
 Set ow = Nothing
End Sub

5.3.2.1 Module1 : Module1.bas

Create a module file and declare the GetComputerName function.

Public Declare Function GetComputerName Lib "kernel32" Alias
"GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

5.3.3 Creating a Transactional Client

This sample code shows how to create a SalesOrderEntry transactional client (SOETxClient => SOETxClient.vbp):

'////SOETxClient////
Private Sub Form_Load()
Dim c As SOEClass2         '// VB SOE transactional object
Set c = New SOEClass2
c.run
Set c = Nothing
End Sub

5.4 Running a Distributed Transaction

This section provides an overview of JD Edwards EnterpriseOne participating in a distributed transaction and discusses how to:

  • Create MTStest for a Distributed Transaction.

  • Create ClientPrj for a Distributed Transaction.

  • Register a New COM+ .dll.

5.4.1 Understanding COM+ Transaction

This sample code, called MTStest.vbp, shows how to create a distributed transaction using COM+. This project contains these two classes:

  • MTSTestClass, which queries and updates a test SQL database.

  • OWTxClass, which runs the Sales Order Entry.

OWTxClass is almost identical to the previous SOETxObject, except that the message box for commit or abort is no longer necessary.

MTStest.dll must be registered in the COM+ Component Services, and the transaction property should be set to required; it might have been set already.

Create a sample SQL test database table SOE2PCTest. SOE2PCTest table has two columns, SONum and LastSONum. The test selects the LastSONum and then updates the table by incrementing the previous value by 1 when commit is called.

Sample code called ClientPrj.vbp will call the transactional object.

Both of the transactions are committed by the DTC when the SetComplete call is made. The DTC aborts the transaction when the SetAbort call is made or if any part of the transaction fails.

Use these steps to run a sales order entry as a distributed transaction in COM+ where the COM connector, JD Edwards EnterpriseOne, and an SQL database participate.

  1. Run the MTStest.vbp.

  2. Run the ClientPrj.vbp.

  3. Click the Call Database_ Test_ Method button.

  4. Switch back to the MTStest and note the sales order number.

  5. When a message box appears to Commit or Abort, select the appropriate action.

  6. Verify in JD Edwards EnterpriseOne whether the sales order has been entered. When the transaction is aborted, the sales order should not be in JD Edwards EnterpriseOne, and the test database should not increment the count.

5.4.2 Creating MTStest for a Distributed Transaction (MTStest.vbp)

This code sample provides detail code for creating MTStest.

Note:

This sample code has message box statements to help better understand the step-by-step flow of the code. Since DTC is managing the transactions, it is necessary not to lock the tables for a long time. When you use message boxes, you stop the program flow. When regression testing, you must remove all of the message boxes. You can write to a log file instead.

5.4.2.1 MTSTestClass : MTStest.bas

You can use this sample code to create MTStest:

Option Explicit
 Public Function Database_Test_Method(_ByVal szConnect As String) As String
 
 Dim stmt As String

 On Error GoTo errhandler

 Dim ctxObject As ObjectContext
 Set ctxObject = GetObjectContext()
      
 Dim MsgBoxRes
 Dim cn As ADODB.Connection
 Dim rsSelect As ADODB.Recordset
 Dim rs As ADODB.Recordset
  
 Set cn = New ADODB.Connection
 With cn
   .ConnectionTimeout = 10
   .ConnectionString = szConnect
   .Open
 End With
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' SONUM and LASTSONUM are columns created in a database called ' 
' COMPLUS. '
' Database server is called soe2pctest.                 '
' LASTSONUM gets incremented when commit is used.            '
' Change these values according to Database created           '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
 Set rs = New ADODB.Recordset
 Set rsSelect = New ADODB.Recordset
 rsSelect.Open "SELECT LASTSONUM FROM soe2pctest", cn, adOpenDynamic, 
_ adLockReadOnly
 Dim i As Integer
 For i = 1 To 3

 stmt = "Update SOE2PCTest set LASTSONUM=" & rsSelect(0).Value + 1& & 
" where SONUM = 1"
 cn.Execute stmt, 1, -1
 rsSelect.Close

 Dim c As OWTXClass
 Set c = New OWTXClass

 c.run

 Set c = Nothing
 cn.Close

 Set rs = Nothing
 Set cn = Nothing
 MsgBoxRes = MsgBox("Do you want to Commit?", vbYesNo, "Transaction 
 Decision")
 If MsgBoxRes = vbYes Then
  ctxObject.SetComplete
 Else
  ctxObject.SetAbort
 End If
 Next I

 Exit Function

errhandler:
 Err.Raise vbObjectError, "MTSTest.MTStest.Database_Test_Method", _ 
Err.Description
 ctxObject.SetAbort
 Exit Function

End Function

5.4.2.2 Module1 : Module1.bas

Create a module file and declare the GetComputerName function.

Public Declare Function GetComputerName Lib "kernel32" Alias
"GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long

5.4.3 Creating ClientPrj for a Distributed Transaction

This code sample provides detail code for creating ClientPrj.vbp.

Note:

This sample code has message box statements to help better understand the step-by-step flow of the code. Since DTC is managing the transactions, it is necessary not to lock the tables for a long time. When you use message boxes, you stop the program flow. When regression testing, you must remove all of the message boxes. You can write to a log file instead.
 Private Sub Command2_Click()
  Dim szConnect As String
  szConnect = "Driver={SQL Server};" & _
     "Server=AServerName;Uid=UserID;Pwd=Passwd;Database=DBName"
  '(NOTE: You may need to change the connection
  ' information to connect to the database.)
 
  Dim obj As Object
  Set obj = CreateObject("MTStest.MTSTestClass")
    
  MsgBox obj.Database_Test_Method(szConnect)
  Set obj = Nothing
  Unload Me
 End Sub

Private Sub Form_Load()
 
  Command2.Caption = "Call Database_Test_Method"

 End Sub

5.4.4 Registering the COM+ .dll

A new COM+ dll (OneWorldinterfaceTx.dll) is provided to be used along with the COM connector to participate in a two-phase commit. OneWorldInterfaceTx.dll must be registered with the COM+ component services.

Use these steps to register OneWorldInterfaceTx.dll:

  1. On the PC, navigate to COM+ Applications:

    Control Panel > Administrative Tools > Component Services

  2. Expand these buttons and folders:

    Component Services > Computers > My Computer

  3. Select COM+ Applications.

  4. Right-click COM+ Applications, select New, and then select Application.

    The COM Application Install Wizard appears.

  5. On Install or Create a New Application, select Create an empty application and then click Next.

  6. On Create Empty Application, enter the name of the application (OneWorldInterfaceTx) that you are registering.

  7. Select an Activation type, and then press Next.

  8. On Set Application Identity, select Interactive User, and then click Next.

  9. Click Finish to close the wizard.

  10. On the PC, expand these folders:

    COM+ Applications > OneWorldInterfaceTx

  11. Select Components.

  12. Right-click Components, select New, and then select Component.

  13. The COM Component Install Wizard appears.

  14. On Import or Install a Component, select Install New Component(s), and then click Next.

  15. On Select New Files to Install, browse to the application (OneWorldInterfaceTx.dll) on the client install directory or the COM interoperability server.

  16. Add the application and then click Next.

  17. Click Finish to close the wizard.

    The application (OneWorldInterfaceTx.dll) is registered.

  18. On the PC, expand the Components folder and then right-click the application (OneWorldInterfaceTx.dll) you just registered.

  19. Select Properties.

  20. On OneWorldInterfaceTx Properties, click the Transactions tab.

  21. For the Transaction support field, select the Required option.

  22. Click OK.

  23. Close the component servers.

The COM connector should be registered using the method described in the chapter titled Installing COM Connector on a Non-JD Edwards EnterpriseOne Client Environment.

The SalesOrderEntry and other wrapper dlls should be registered using the standard RegSvr32 command.

A new transactional object that is going to participate in the COM+ transactions (for example, SOEClass2.dll) must be created and registered through the COM+ component services of the administrative tools. The transactions property of this object should be set to Required. This transactional object will use the new OneWorldInterfaceTx.dll for starting a transaction, executing a business function, and so on. The code outline is explained in Case1: JD Edwards EnterpriseOne Participates in COM+ Transaction. Detail sample code for the SalesOrderEntry transaction object (SOETxObject) is provided.

After the transactional object is created, open a new VB sample SalesOrderEntry client and call the SOEClass2 object. The VB SOETxClient code is provided.

Two cases of the Sales Order Entry application are discussed. Case 1 is when JD Edwards EnterpriseOne participates in the COM+ transaction. Case 2 is when JD Edwards EnterpriseOne participates in a distributed transaction.