Save multiple group permissions in one go
There's no need for fairly meaningless variable names like gsp, conn, tran, eItem,...

And result is equally bad, since it doesn't tell me what it contains.

Exception x is... unexpected. ex or exc is usually used.



You use var, but not consistently. Why SqlConnection conn, Group group, etc.?



I'm sure the .ToString() isn't necessary in "ProductName.GSP.cid" + companyID.ToString() -- unless you're coding to an old version of .NET.



Comments shouldn't tell me what is happening, but why. //End outer for and //important :) don't tell me anything useful. 

Meanwhile //new permission that does not exist in the database. (INSERT) tells me that if (stepPermission.RowID == 0) isn't perhaps the best way to check if you need to do an insert or an update.



An enum shouldn't be called StatusEnum. Why not simply Status?



GroupStepPermissions is a class name, yet it seems to represent a single item. That's a big no-no.



Avoid concatenation:

"Added rights for '" + group.Name + "' in step '" + stepPermission.StepTitle + "'"


This is why string.Format() was invented.



Now, let's look at the whole method. You have four parameters, which is bordering on getting hard to maintain. Consider a class that contains companyID, groups and gsp. Note that I leave connectionString out of it; quite frankly I find it odd to see you pass a connectionstring to a method.

There's a lot of semi-duplicate logic, especially in catch (Exception x) in the insert or update. Move that to a method and call it with the required parameters. 

I'd also be inclined to move everything inside foreach (GroupStepPermissions stepPermission in gsp) to a separate method, if only to reduce all those indentations.

I don't see the point in doing this:

result.Add(new EventItem("Insert Step permissions"));
result.Add(new EventItem("Update Step permissions"));


...if that results in having to do this:

result[0].SubEvents.Add


Name one of them insertEventItem and the other updateEvenItem and only compile the result list at the end, e.g.

return new List&lt;EventItem&gt;{ insertEventItem, updateEvenItem };