Para criar aplicações altamente escaláveis, os recursos do servidor de dados e da camada intermediária devem ser liberados o mais rápido possível.

Você tem um objeto servidor que fornece recordsets desconectados
Public Function getRS() As Redordset
Public Function setRS(rs As Recordset) As Boolean
E um cliente que usa este servidor
Dim obj As New ADOServer.Data
Set rs = obj.getRS()
' faz algumas mudanças no recordset aqui
obj.setRS rs (atente para esta linha)
O que acontece quando o recordset é passado entre o cliente e o servidor?
Bem, depende ...
Quando ambos os objetos estão no mesmo processo, é passado um ponteiro.
Mas você não pode passar ponteiros entre fronteiras de processos ou máquinas.
- HTTP ou DCOM
No lugar, é usado Marshalling (condução) para mover o recordset entre os processos.
O seu código pode ser o mesmo
Mas o desempenho é bem diferente

Assuma que rs tem 5000 linhas.
- Set rs = obj.getRs ' isto toma 2.2 segundos
- Isto implica em passar uma vez o rs entre os processos.
- obj.setRS rs ' isto levará 4.4 segundos
- rs é passado em ambas as direções!
Normalmente, o cliente não precisa ver qualquer mudança que o servidor tenha feito, portanto, modifique a definição da função do servidor para:
Public Funcion setRS ( ByVal rs As Recordset ) As Boolean

obj.setRS rs ' irá consumir 2.2 segundos agora
porque rs não é passado de volta para o cliente
Habitualmente, o servidor precisa apenas saber os registros que o cliente modificou. Assim, no código cliente atribua:
rs.MarshalOptions = adMarshalModifiedOnly
obj.setRS rs ' irá consumir agora 0.2 segundos
Se recordsets desconectados são atualizáveis, eles costumam usar o tipo de bloqueio BatchOptimistic.
Isto permite que o cliente faça atualizações ao recordset sem estar contectado
O recordset "recorda" cada atualização feita pelo cliente
O cliente passa o recordset de volta à camada intermediária
A camada intermediária se reconecta ao banco de dados e faz a atualização em batch
Para cada registro modificado, o processo de atualização em batch gera um comando SQL
Por padrão, até 15 comandos SQL são reunidos e passados por vez ao banco de dados.
Este padrão pode ser modificado: rs.Properties("Batch Size") = 1
Batches em quantidade suficiente são submetidos para processar todas as mudanças
Durante uma atualização batch, algumas mudanças podem ser bem sucedidas e outras falharem, portanto, o controle de transações é vital para garantir a consistência do processo de atualização em batch:
- No MTS ou COM+, isto significa configurar o atributo de transação do componente que esteja fazendo as atualizações de modo que ele rode numa transação
- Fora do MTS ou COM+, isto significa fazer uso dos métodos de transação do objeto Connection
Public Function setRS(ByVal rs As Recordset) As Variant
On Error GoTo ErrH
rs.ActiveConnection = CONNECTION_STRING
rs.ActiveConnection.BeginTrans
rs.UpdateBatch
rs.ActiveConnection.CommitTrans
rs.ActiveConnection = Nothing
setRS = Null
Exit Function
ErrH:
setRS = Err.Description
rs.ActiveConnection.RollbackTrans
Set rs.ActiveConnection = Nothing
End Function
É muito comum fazer-se algum pré-processamento (validação) e pós-processamento (tratamento de erros)
On Error Goto ErrH
rs.ActiveConnection.BeginTrans
validate(rs)
rs.UpdateBatch
rs.ActiveConnection.CommitTrans
Exit Function
ErrH:
processErrors(rs)
rs.ActiveConnection.RollbackTrans