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;
}
}
}