Custom Autonumber using a Trigger

Does it have to increment by 1? I don't like implementing auto numbers in a trigger because if you have two concurrent transactions creating an account, they might both query for the max number at the same time and you get duplicates. I prefer to use the built in auto-number feature. It skips numbers since it does it across all record types, but you can be confident they won't repeat.

Also, you should never hard code IDs in your code - they change when going from sandbox to production. It is much better to reference RecordType.DeveloperName.


You're setting maxlead before your loop so it's the same value for all Accounts within the trigger context. For instance, if you use Data Loader to load 50 Accounts, the value for maxlead is set to some number and stays the same for all 50 Accounts in your loop, since it's generated at the beginning of the trigger context.

Do you want it to just increment from the first maxlead value? Update it to this:

trigger AutonumberRecTypeCustomer on Account (before insert, before update) {

    list<Account> Acc= [SELECT Id,Name,Customer_Number__c FROM Account WHERE Customer_Number__c !=:null order by Customer_Number__c desc limit 1];
    decimal maxlead = Acc[0].Customer_Number__c;    

    for(Account Acci:Trigger.new){
        if(Acci.RecordTypeId =='012a3456789BCde'){
            Acci.Customer_Number__c = Integer.valueOf(maxlead)+1;
            maxlead++;
        }
    }  
}

If it is critical to avoid duplicates you will also have to work Locking Statements. These allow one transaction to stop another transaction from progressing until the first transaction has released the lock. So if two requests happen at the same time - e.g. 2 users or a user and the data loader - they are made to execute in turn.

Unfortunately it isn't easy logic to get right and the platform's test environment doesn't give you any mechanisms to write effective tests.

Take a look at the various postings on this site on for-update for more information.

Tags:

Trigger