You are performing DML inside the for
loop, thats why the error is. Update contact outside of for
loop
//loop through each account
for(Account a: accounts)
{
//all your existing logic to prepare contacts list, except DML operation.
}
//Update all affected contacts
update contacts;
Refer Apex Code Best Practices
Update based on this following comments
Tried to change One of ACCOUNT OWNER Error:: caused by: System.QueryException: Non-selective query against large object type (more than 200000 rows). Consider an indexed filter or contact salesforce.com about custom indexing. Even if a field is indexed a filter might still not be selective when: 1. The filter value includes null (for instance binding with a list that contains null) 2. Data skew exists whereby the number of matching rows is very large (for instance, filtering for a particular foreign key value that occurs many times): Trigger.UpdateRightNowContacts: line 13, column 1
Solution
This is typical design flaws where a single account contains more than 10000 Contacts which is called Account Data Skew.
It is recommended to distribute the Contacts under different accounts so that a single Account should not have 10000 contacts.
Secondly, to perform query optimization, request Salesforce to create Custom Indexes so that not only this query, but also, List Views, Reports performance must be enhanced using those indexes.
Refer Avoid Account Data Skew for Peak Performance
Improve performance with Custom indexes using Selective SOQL Queries
Thirdly, if there are large volume for records to be updated, consider using batch processes.