Classe OrderCOM.cs (Transactions distribuées)

 

using System;

using System.Collections;

using System.Data;

using System.Data.SqlClient;

using System.EnterpriseServices;

using System.Runtime.InteropServices;

 

namespace PetShop.Components {

      [Transaction]

      [ClassInterface(ClassInterfaceType.AutoDispatch)]

      public class OrderCOM  {

            private const string SQL_INSERT_ORDER = "INSERT INTO Orders VALUES(@UserId, @Date, @ShipAddress1, @ShipAddress2, @ShipCity, @ShipState, @ShipZip, @ShipCountry, @BillAddress1, @BillAddress2, @BillCity, @BillState, @BillZip, @BillCountry, 'UPS', @Total, @BillFirstName, @BillLastName, @ShipFirstName, @ShipLastName, @CardNumber, @CardExpiration, @CardType, 'US_en'); SELECT @@IDENTITY";

            private const string SQL_INSERT_STATUS = "INSERT INTO OrderStatus VALUES(@OrderId, @OrderId, GetDate(), 'P')";

            private const string SQL_INSERT_ITEM = "INSERT INTO LineItem VALUES(@OrderId, @LineNumber, @ItemId, @Quantity, @Price)";

            private const string SQL_UPDATE_INVENTORY = "UPDATE Inventory SET Qty = Qty - @Quantity WHERE ItemId = @ItemId";

            private const string PARM_USER_ID = "@UserId";

            private const string PARM_DATE = "@Date";

            private const string PARM_SHIP_ADDRESS1 = "@ShipAddress1";

            private const string PARM_SHIP_ADDRESS2 = "@ShipAddress2";

            private const string PARM_SHIP_CITY = "@ShipCity";

            private const string PARM_SHIP_STATE = "@ShipState";

            private const string PARM_SHIP_ZIP = "@ShipZip";

            private const string PARM_SHIP_COUNTRY = "@ShipCountry";

            private const string PARM_BILL_ADDRESS1 = "@BillAddress1";

            private const string PARM_BILL_ADDRESS2 = "@BillAddress2";

            private const string PARM_BILL_CITY = "@BillCity";

            private const string PARM_BILL_STATE = "@BillState";

            private const string PARM_BILL_ZIP = "@BillZip";

            private const string PARM_BILL_COUNTRY = "@BillCountry";

            private const string PARM_TOTAL = "@Total";

            private const string PARM_BILL_FIRST_NAME = "@BillFirstName";

            private const string PARM_BILL_LAST_NAME = "@BillLastName";

            private const string PARM_SHIP_FIRST_NAME = "@ShipFirstName";

            private const string PARM_SHIP_LAST_NAME = "@ShipLastName";

            private const string PARM_CARD_NUMBER = "@CardNumber";

            private const string PARM_CARD_EXPIRATION = "@CardExpiration";

            private const string PARM_CARD_TYPE = "@CardType";

            private const string PARM_ORDER_ID = "@OrderId";

            private const string PARM_LINE_NUMBER = "@LineNumber";

            private const string PARM_ITEM_ID = "@ItemId";

            private const string PARM_QUANTITY = "@Quantity";

            private const string PARM_PRICE = "@Price";

            private const string ACID_USER_ID = "ACID";

            private const string ACID_ERROR_MSG = "ACID test exception thrown for distributed transaction!";

 

            [AutoComplete]

            public void Insert(Order order) {

                  SqlParameter[] orderParms = GetOrderParameters();

                  SqlParameter[] itemParms = GetItemParameters();

                  SqlParameter[] inventoryParms = GetInventoryParameters();

                  SqlParameter statusParm = new SqlParameter(PARM_ORDER_ID, SqlDbType.Int);

 

                  orderParms[0].Value = order.userId;

                  orderParms[1].Value = order.date;

                  orderParms[2].Value = order.shippingAddress.address1;

                  orderParms[3].Value = order.shippingAddress.address2;

                  orderParms[4].Value = order.shippingAddress.city;

                  orderParms[5].Value = order.shippingAddress.state;

                  orderParms[6].Value = order.shippingAddress.zip;

                  orderParms[7].Value = order.shippingAddress.country;

                  orderParms[8].Value = order.billingAddress.address1;

                  orderParms[9].Value = order.billingAddress.address2;

                  orderParms[10].Value = order.billingAddress.city;

                  orderParms[11].Value = order.billingAddress.state;

                  orderParms[12].Value = order.billingAddress.zip;

                  orderParms[13].Value = order.billingAddress.country;

                  orderParms[14].Value = order.cart.GetTotal();

                  orderParms[15].Value = order.billingAddress.firstName;

                  orderParms[16].Value = order.billingAddress.lastName;

                  orderParms[17].Value = order.shippingAddress.firstName;

                  orderParms[18].Value = order.shippingAddress.lastName;

                  orderParms[19].Value = order.cardNumber;

                  orderParms[20].Value = order.cardExpiration;

                  orderParms[21].Value = order.cardType;

                 

                  order.orderId = Convert.ToInt32(Database.ExecuteScalar(Database.CONN_STRING2, CommandType.Text, SQL_INSERT_ORDER, orderParms));

 

                  statusParm.Value = order.orderId;

 

                  Database.ExecuteNonQuery(Database.CONN_STRING2, CommandType.Text, SQL_INSERT_STATUS, statusParm);

 

                  int i = 1;

 

                  foreach (CartItem item in order.cart) {

                        itemParms[0].Value = order.orderId;

                        itemParms[1].Value = i++;

                        itemParms[2].Value = item.Item.Id;

                        itemParms[3].Value = item.Quantity;

                        itemParms[4].Value = item.Item.Price;

 

                        Database.ExecuteNonQuery(Database.CONN_STRING2, CommandType.Text, SQL_INSERT_ITEM, itemParms);

                            

                        inventoryParms[0].Value = item.Quantity;

                        inventoryParms[1].Value = item.Item.Id;

                 

                        Database.ExecuteNonQuery(Database.CONN_STRING1, CommandType.Text, SQL_UPDATE_INVENTORY, inventoryParms);

                  }

 

                  if (order.userId == ACID_USER_ID)

                        throw new ApplicationException(ACID_ERROR_MSG);

            }

           

            private static SqlParameter[] GetOrderParameters() {

                  SqlParameter[] parms = Database.GetCachedParameters(SQL_INSERT_ORDER);

                 

                  if (parms == null) {

                        parms = new SqlParameter[] {

   new SqlParameter(PARM_USER_ID, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_DATE, SqlDbType.DateTime),

                          new SqlParameter(PARM_SHIP_ADDRESS1, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_SHIP_ADDRESS2, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_SHIP_CITY, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_SHIP_STATE, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_SHIP_ZIP, SqlDbType.VarChar, 50),

                          new SqlParameter(PARM_SHIP_COUNTRY, SqlDbType.VarChar, 50),

                          new SqlParameter(PARM_BILL_ADDRESS1, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_BILL_ADDRESS2, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_BILL_CITY, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_BILL_STATE, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_BILL_ZIP, SqlDbType.VarChar, 50),

                          new SqlParameter(PARM_BILL_COUNTRY, SqlDbType.VarChar, 50),

                          new SqlParameter(PARM_TOTAL, SqlDbType.Decimal),

                          new SqlParameter(PARM_BILL_FIRST_NAME, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_BILL_LAST_NAME, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_SHIP_FIRST_NAME, SqlDbType.VrChar, 80),

                          new SqlParameter(PARM_SHIP_LAST_NAME, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_CARD_NUMBER, SqlDbType.VarChar, 80),

                          new SqlParameter(PARM_CARD_EXPIRATION, SqlDbType.Char, 10),

                          new SqlParameter(PARM_CARD_TYPE, SqlDbType.VarChar, 80)};

 

                        Database.CacheParameters(SQL_INSERT_ORDER, parms);

                  }

 

                  return parms;

            }

 

            private static SqlParameter[] GetItemParameters() {

                  SqlParameter[] parms = Database.GetCachedParameters(SQL_INSERT_ITEM);

           

                  if (parms == null) {

                        parms = new SqlParameter[] {

                                 new SqlParameter(PARM_ORDER_ID, SqlDbType.Int),

                                 new SqlParameter(PARM_LINE_NUMBER, SqlDbType.Int),

                                 new SqlParameter(PARM_ITEM_ID, SqlDbType.Char, 10),

                                 new SqlParameter(PARM_QUANTITY, SqlDbType.Int),

                                 new SqlParameter(PARM_PRICE, SqlDbType.Decimal)};

 

                        Database.CacheParameters(SQL_INSERT_ITEM, parms);

                  }

 

                  return parms;

            }

 

            private static SqlParameter[] GetInventoryParameters() {

                  SqlParameter[] parms = Database.GetCachedParameters(SQL_UPDATE_INVENTORY);

                 

                  if (parms == null) {

                        parms = new SqlParameter[] {

                                      new SqlParameter(PARM_QUANTITY, SqlDbType.Int),

                                      new SqlParameter(PARM_ITEM_ID, SqlDbType.Char, 10)};

 

                        Database.CacheParameters(SQL_UPDATE_INVENTORY, parms);

                  }

 

                  return parms;

            }

      }

}