s-LCTrans-cs

//****************************************************************************
// (c) Copyright IBM Corp. 2007 All rights reserved.
//
// The following sample of source code ("Sample") is owned by International
// Business Machines Corporation or one of its subsidiaries ("IBM") and is
// copyrighted and licensed, not sold. You may use, copy, modify, and
// distribute the Sample in any form without payment to IBM, for the purpose
// of assisting you in the development of your applications.
//
// The Sample code is provided to you on an "AS IS" basis, without warranty
// of any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, EITHER EXPRESS
// OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Some jurisdictions
// do not allow for the exclusion or limitation of implied warranties, so the
// above limitations or exclusions may not apply to you. IBM shall not be
// liable for any damages you suffer as a result of using, copying, modifying
// or distributing the Sample, even if IBM has been advised of the
// possibility of such damages.
//
//**************************************************************************
//
// SOURCE FILE NAME: LCTrans.cs
//
// SAMPLE: Demonstrates loosely coupled transactions
//         with the DB2 .NET Data Provider
//
// SQL Statement USED:
//         SELECT
//
// DB2 .NET Data Provider Classes USED:
//         DB2Connection
//         DB2Command
//         
//                           
//****************************************************************************
//
// Building and Running the sample program 
//
// Using the bldapp.bat batch file: 
//
// 1. Create a new key pair and store it in SubCOM.snk by entering the 
//    following at the command prompt:
//
//     sn -k SubCOM.snk
//
// 2. Compile the SubCOM.cs file with bldapp.bat by entering the following 
//    at the command prompt:
//
//      bldapp SubCOM
// 
// 3. Create a new key pair and store it in RootCOM.snk by entering the 
//    following at the command prompt:
//
//      sn -k RootCOM.snk
//
// 4. Compile the RootCOM.cs file with bldapp.bat by entering the following 
//    at the command prompt:
//
//      bldapp RootCOM
// 
// 5. Compile the LCTrans.cs file with bldapp.bat by entering the following 
//    at the command prompt:
//
//      bldapp LCTrans
//  
// 6. Register the COM+ objects with regCOM.bat by entering the following   
//    at the command prompt:
//
//      regCOM
//
// 7. Run the LCTrans program by entering the program name at the command 
//    prompt followed by a user id and password for the SAMPLE database:
//
//      LCTrans <userid> <password>
//
// Using the makefile:
//
// 1  Build the assembly SubCOM.dll and RootCOM.dll and compile LCTrans.cs
//    with the makefile by entering the following at the command prompt:
//
//      nmake LCTrans
//
// 2. Register the COM+ objects with regCOM.bat by entering the following   
//    at the command prompt:
//
//      regCOM
//
// 3. Run the LCTrans program by entering the program name at the command 
//    prompt followed by a user id and password for the SAMPLE database:
//
//      LCTrans <userid> <password>
//
//****************************************************************************
//
// For more information on the sample programs, see the README file.
//
// For information on developing applications, see the Application
// Development Guide.
//
// For information on using SQL statements, see the SQL Reference.
//
// For the latest information on programming, compiling, and running DB2
// applications, visit the DB2 Information Center at
//     http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp
//
//****************************************************************************
using  System.EnterpriseServices;
using System;
using System.IO;
using System.Data;
using IBM.Data.DB2;
using Microsoft.VisualBasic;
using System.Reflection;
using System.Runtime.InteropServices;
using RootCOM;

class  LCTrans
{
        public static String strUID = "";
        public static String strPWD = "";
        public static String strEmpJob;
        public static void Main(String[] CmdArgs)
        {
                Decimal decIncrease = 5000;
                String strNewJob = "Mgr";
                String strOldJob;
                UpdateEmpInfoCOM comRootCOM;

                Console.WriteLine();
                Console.WriteLine("  THIS SAMPLE DEMONSTRATES LOOSELY COUPLED TRANSACTIONS IN DB2\n" +
                                                  "  USING MICROSOFT .NET");
                Console.WriteLine();

                // Check if the user id and password have been entered
                switch (CmdArgs.Length)
                {
                        case 0:
                                strUID = null;
                                strPWD = null;
                                break;
                        case 2:
                                // Obtain the user id and password
                                strUID = Convert.ToString(CmdArgs[0]);
                                strPWD = Convert.ToString(CmdArgs[1]);
                                break;
                        default:
                                Console.WriteLine("  Invocation:");
                                Console.WriteLine();
                                Console.WriteLine("  LCTrans");
                                Console.WriteLine("  or");
                                Console.WriteLine("  LCTrans <USERID> <PASSWORD>");
                                return;
                }

                Console.WriteLine("\n  DEMONSTRATE LOOSELY COUPLED TRANSACTION IN WHICH ONE" +
                                                  " FAILS CAUSING\n  BOTH TO ROLLBACK\n");

                // Display the salary and job title of employee id = 320 before the transaction
                Console.WriteLine("\n  EMPLOYEE INFO BEFORE THE TRANSACTION\n");

                PrintEmpInfo(320, ref strEmpJob);

                // Create a RootCOM instance. The root component invokes a sub component to demonstrate loosely coupled transactions
                comRootCOM = new UpdateEmpInfoCOM();

                // Demonstrate a case where one operation of the transaction fails causing both
                // operaions to be rolled back. Employee id = 320 has been an employee
                // for less 5 years and so, should not have a salary > 20000. 
                // The sub component aborts the transaction because it finds the salary of empid 320 will be greater than 20000

                comRootCOM.UpdateEmpInfo(320, decIncrease, strNewJob, strUID, strPWD);

                // Display the salary and job title of employee id = 320 after the transaction
                // Nothing should be changed because of the rollback in the sub component.
                Console.WriteLine("\n  EMPLOYEE INFO AFTER THE TRANSACTION\n");
                PrintEmpInfo(320, ref strEmpJob);

                // Demonstrate a case where all operations are successful causing
                // them to be committed.
                Console.WriteLine( "\n\n  DEMONSTRATE LOOSELY COUPLED TRANSACTIONS THAT ARE COMPLETED" +
                                                   "\n  SUCCESSFULLY AND ARE THEREFORE COMMITTED\n" );

                // Display the salary and job title of employee id = 320 before the transaction
                Console.WriteLine("\n  EMPLOYEE INFO BEFORE THE TRANSACTION\n");

                PrintEmpInfo(20, ref strEmpJob);

                //Save the old job so we can do the unchanges
                strOldJob = strEmpJob;

                comRootCOM = new UpdateEmpInfoCOM();
                comRootCOM.UpdateEmpInfo(20, decIncrease, strNewJob, strUID, strPWD);

                // Display the salary and job title of employee id = 20 after the transaction
                // They should be changed.

                Console.WriteLine("\n  EMPLOYEE INFO AFTER THE TRANSACTION\n");
                PrintEmpInfo(20, ref strEmpJob);

                // Undo the changes made to the SAMPLE database
                Console.WriteLine("\n  UNDO THE CHANGES MADE TO THE 'SAMPLE' DATABASE");

                comRootCOM = new UpdateEmpInfoCOM();
                comRootCOM.UpdateEmpInfo(20, -decIncrease, strOldJob, strUID, strPWD);

                Console.WriteLine("\n  EMPLOYEE INFO AFTER THE UNDO\n");

                PrintEmpInfo(20, ref strEmpJob);

                return;
        
        }

        // This method displays the job title and salary of the employee
        // with id = empID
        public static void PrintEmpInfo(int IntEmpID, ref String StrJob)
        {
                Decimal  decEmpSalary;
                DB2Connection objConnection;
                DB2Command objCommand = new DB2Command();
                DB2DataReader objReader;

                if (strUID == "")
                {
                        objConnection = new DB2Connection("database=sample;enlist=false");
                }
                else
                {
                        objConnection = new DB2Connection("database=sample;UID=" + 
                                                          strUID + ";PWD=" + strPWD + 
                                                          ";enlist=false");
                }
        
                // Connect to the SAMPLE database
                try
                {
                        objConnection.Open();
                }
                catch (Exception e)
                {
                        Console.WriteLine( "LCTrans: Failed to open connection to the SAMPLE database!");
                        Console.WriteLine(e.ToString());
                        return;
                }

                objCommand.CommandText = "select SALARY, JOB from STAFF where ID = " + IntEmpID;
                objCommand.Connection = objConnection;

                // Execute the query
                try
                {
                        objReader = objCommand.ExecuteReader();
                        if (objReader.Read()) 
                        {
                                decEmpSalary = objReader.GetDecimal(0);
                                StrJob = objReader.GetString(1);

                                // Display the details of the employee
                                Console.WriteLine( "  Salary of employee id = " + IntEmpID + " in table STAFF: " + decEmpSalary);
                                Console.WriteLine("  Job of employee id = " + IntEmpID + " in table STAFF: " + StrJob);
                        }
                        
                        objReader.Close();
                }
                catch (Exception e)
                {
                        Console.WriteLine("LCTrans: Failed to fetch from table STAFF!");
                        Console.WriteLine(e.ToString());
                }

                objConnection.Close();
        }
}