Large Transactions

Posts   
 
    
Dmeierotto
User
Posts: 10
Joined: 30-Jul-2004
# Posted on: 30-Jul-2004 18:48:45   

The issue is adding an entity to a transaction collection iteratively, and the creation of unnecessary overhead.

Example Code:

Transaction transactionManager = 
   new Transaction(IsolationLevel.ReadCommitted, "My Trans");

try{
    foreach(Entity myEntity in SomeColl){
        myEntity.MyProperty = “SomeValue”;
        transactionManager.Add(myEntity);
        myEntity.Save();
        //Could I remove the entity from the transaction here?
    }

    transactionManager.Commit();
catch{
    transactionManager.Rollback();
}

1- Could I just set the transaction property of the entity object to the transaction object?

myEntity.Transaction = transactionManager;

2- Or, could I add the object to the transaction collection, execute the save, and then remove the entity from the transaction collection.

Option 1 or option 2 would resolve this problem if they work. Could you verify which of the options, if possible, would be best practice?

Thanks, Dan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39951
Joined: 17-Aug-2003
# Posted on: 31-Jul-2004 11:44:56   

Dmeierotto wrote:

The issue is adding an entity to a transaction collection iteratively, and the creation of unnecessary overhead.

Example Code:

Transaction transactionManager = 
   new Transaction(IsolationLevel.ReadCommitted, "My Trans");

try{
    foreach(Entity myEntity in SomeColl){
        myEntity.MyProperty = “SomeValue”;
        transactionManager.Add(myEntity);
        myEntity.Save();
        //Could I remove the entity from the transaction here?
    }

    transactionManager.Commit();
catch{
    transactionManager.Rollback();
}

You could also save the entities in 1 go by calling SaveMulti() of the collection. You can also add the collection to a transaction, if you want hte SaveMulti() to participate in an existing transaction: // code using transactionManager //... transactionManager.Add(SomeColl);

SomeColl.SaveMulti();

This will save all entities in SomeColl in a transaction: OR a new one if the collection isn't part of an existing transaction, OR the transaction the collection was added to simple_smile

1- Could I just set the transaction property of the entity object to the transaction object?

myEntity.Transaction = transactionManager;

No, use the Add() method. This makes sure the overhead required behind the scenes is been taken care of. Imagine this: You save two order entities with an identity column in a transaction. The second one fails. However the first is refetched and its ID is loaded with a value. However that's not a valid value because the transaction rolled back. So the code rolls back the internal values as well. This has to be setup first, which is done by the Transaction object's Add method.

2- Or, could I add the object to the transaction collection, execute the save, and then remove the entity from the transaction collection.

All participating objects are removed from the transaction object automatically when Rollback or Commit is called. So you don't have to do anything after the transaction object is rolled back or committed. simple_smile

Option 1 or option 2 would resolve this problem if they work. Could you verify which of the options, if possible, would be best practice?

Best practise: - when saving a collection, use the SaveMulti() methods (one of the overloads). This will create an own transaction if the collection isn't added to a transaction, otherwise it will use the transaction it's added to. - when a save action has to be done inside a transaction, use Add() to add the object to the transaction. this can be an entity or an entitycollection - when commit or rollback is called, entities (and collections) are automatically removed from the transaction object. The transaction object is not usable after a commit/rollback. Rollback ensures that internal datastructures inside an entity are rolled back as well.

Frans Bouma | Lead developer LLBLGen Pro
Dmeierotto
User
Posts: 10
Joined: 30-Jul-2004
# Posted on: 02-Aug-2004 15:56:13   

Dmeierotto wrote:

2- Or, could I add the object to the transaction collection, execute the save, and then remove the entity from the transaction collection.

Otis wrote:

All participating objects are removed from the transaction object automatically when Rollback or Commit is called. So you don't have to do anything after the transaction object is rolled back or committed. simple_smile

This was not quite what I meant, but a good peice of info. What I meant was:


.
.
.
    foreach(Entity myEntity in SomeColl){
        myEntity.MyProperty = “SomeValue”;
        transactionManager.Add(myEntity);
        myEntity.Save();
        transactionManager.Remove(myEntity);//Would this line be safe??
    }
.
.
.
transactionManager.Commit();

Would removing the object from the transaction be safe, BEFORE calling commit but AFTER calling the Entity object's Save() method?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39951
Joined: 17-Aug-2003
# Posted on: 02-Aug-2004 16:25:06   

Dmeierotto wrote:

Dmeierotto wrote:

2- Or, could I add the object to the transaction collection, execute the save, and then remove the entity from the transaction collection.

Otis wrote:

All participating objects are removed from the transaction object automatically when Rollback or Commit is called. So you don't have to do anything after the transaction object is rolled back or committed. simple_smile

This was not quite what I meant, but a good peice of info. What I meant was:

I tried to explain how the mechanism worked so it would give more insight in when to do what. As I explained, some housekeeping is done behind the scenes. It is obvious that removing an entity from the transaction before rollback/commit would not be very wise.


.
.
.
    foreach(Entity myEntity in SomeColl){
        myEntity.MyProperty = “SomeValue”;
        transactionManager.Add(myEntity);
        myEntity.Save();
        transactionManager.Remove(myEntity);//Would this line be safe??
    }
.
.
.
transactionManager.Commit();

Would removing the object from the transaction be safe, BEFORE calling commit but AFTER calling the Entity object's Save() method?

No, never do that as with a Rollback, your entity is not rolledback internally.

May I ask why you want to remove the entities from the transaction when they're removed from the transaction automatically when the transaction is ended? simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Dmeierotto
User
Posts: 10
Joined: 30-Jul-2004
# Posted on: 16-Aug-2004 20:43:49   

Otis wrote:

May I ask why you want to remove the entities from the transaction when they're removed from the transaction automatically when the transaction is ended? simple_smile

The reason I am concerned with this is that I have a couple large updates where 10000s of records are being included in the transaction before the commit is called. If I understand the transaction collection correctly, my transaction object could get unessarily large.

Of course I can lower the commit threshold, but I was just curious if there were alternatives to the large transaction collection. - Thanks, Dan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39951
Joined: 17-Aug-2003
# Posted on: 16-Aug-2004 21:15:41   

AH I see.

Well, in theory there shouldn't be a problem with the size of a transaction object, but it might be that inserts in the collections can take longer than necessary.

I'm not sure if you're loading 10,000 objects into memory, alter them and then save them again, if you do that, it's probably more efficient to do the updates directly in the database, using the mechanisms build into LLBLGen Pro. (UpdateMulti() method in every entitycollection)

If you're transfering data from one db to another, it might be an option to use bulk updates like DTS can provide you. But I'm not sure what the particular reason is why you're saving 10,000 objects or more in one go.

Frans Bouma | Lead developer LLBLGen Pro