AbleCommerce, CommerceBuilder, database transaction safety
Posted: Sat May 23, 2009 9:24 am
I'm trying to figure out how to make a series of CommerceBuilder API calls happen within a DB transaction.
We have working code that using CB to import orders from a 3rd party. It uses pure CommerceBuilder APIs. It doesn't make any proprietary DB connections. Here are a few sparse pieces of the import code just to give a flavor of the call patterns:
The import process works fine. BUT if I attempt to wrap the otherwise working code in a transaction as follows:
Somewhere during the import where all the CommerceBuilder calls are being made, I get a transaction deadlock exception:
This to me indicates that when using the CommerceBuilder APIs, they don't always use the same DB connection that is exposed via Token.Instance.Database. ie, sometimes they hit the DB in a different connection.
Can someone please help me understand how the DB connections and transactions are setup? We -have- to have reliable transactionality if we're going to customize and grow our website using the CommerceBuilder APIs. It makes me wonder if the transactionality is truly safe in the rest of the off the shelf AbleCommerce code too (ie the Admin web pages).
thanks
We have working code that using CB to import orders from a 3rd party. It uses pure CommerceBuilder APIs. It doesn't make any proprietary DB connections. Here are a few sparse pieces of the import code just to give a flavor of the call patterns:
Code: Select all
CheckoutRequest checkoutRequest = new CheckoutRequest(null);
CheckoutResponse checkoutResponse = basket.Checkout(checkoutRequest);
Order order = OrderDataSource.Load(checkoutResponse.OrderId);
....
User user = UserDataSource.CreateUserInstance();
user.Save();
user.Basket.Save();
basket = user.Basket;
basket.Clear();
Address billAddress = user.PrimaryAddress;
//parse name
ParsedName BillToName = new ParsedName(fields[5]);
billAddress.FirstName = BillToName.FirstName;
billAddress.LastName = BillToName.LastName;
billAddress.Email = fields[4];
billAddress.Phone = fields[6];
billAddress.Save();
Product p = ProductDataSource.LoadForCriteria(string.Format("Sku = '{0}'", sku))[0];
BasketItem item = BasketItemDataSource.CreateForProduct(p.ProductId, qty);
item.BasketId = basket.BasketId;
basket.Items.Add(item);
Code: Select all
Token.Instance.Database.BeginTransaction(IsolationLevel.Serializable);
DoImportWork();
Token.Instance.Database.CommitTransaction();
Code: Select all
[SqlException (0x80131904): Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1950890
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4846875
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2392
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +204
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +175
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137
CommerceBuilder.Data.Database.ExecuteNonQuery(DbCommand command) +233
CommerceBuilder.Orders.Basket.a(Basket A_0, Boolean A_1) +632
CommerceBuilder.Orders.Basket.Clear() +10
Can someone please help me understand how the DB connections and transactions are setup? We -have- to have reliable transactionality if we're going to customize and grow our website using the CommerceBuilder APIs. It makes me wonder if the transactionality is truly safe in the rest of the off the shelf AbleCommerce code too (ie the Admin web pages).
thanks