Você pode usar transações para forçar a consistência entre coleções que contêm dados duplicados. As transação atualizam várias coleções em uma única operação atômica.
Use transação para reforçar a consistência se sua aplicação precisar sempre retornar dados atualizados e puder tolerar possíveis impactos negativos no desempenho durante períodos de leituras pesadas.
As transações talvez não tenham o mesmo desempenho que outros métodos de impor consistência de dados. O desempenho de leitura pode ser impactado negativamente enquanto uma transação está aberta. Porém, as transações garantem que os dados lidos pelo cliente sejam sempre atuais.
Sobre esta tarefa
Para usar transações, você deve se conectar a um conjunto de réplicas ou cluster fragmentado. Não é possível usar transações em implantações autônomas.
Antes de começar
Analise os diferentes métodos para forçar a consistência dos dados e garantir que as transações sejam a melhor abordagem para seu aplicativo. Para saber mais, consulte Consistência de dados.
Passos
O exemplo a seguir reforça a consistência dos dados em um aplicativo de comércio eletrônico. O esquema de exemplo duplica as informações do produto nas coleções products e sellers. Esse projeto de esquema otimiza as consultas tanto para produtos quanto para vendedores.
Quando um produto é atualizado, como quando o preço muda, é fundamental que o preço seja consistente na coleção products e na coleção sellers. Portanto, as transações são um método razoável para forçar a consistência dos dados nesse aplicativo.
Criar a coleção de vendedores
use test db.sellers.insertOne( { id: 456, name: "Cool Clothes Co", location: { address: "21643 Andreane Shores", state: "Ohio", country: "United States" }, phone: "567-555-0105", products: [ { name: "sweater", price: 30 }, { name: "t-shirt", price: 10 }, { name: "vest", price: 20 } ] } )
Configurar uma transação para manipular atualizações
Observação
O exemplo a seguir usa uma transação em mongosh. Para ver exemplos de transação para drivers do MongoDB, consulte Transações.
O exemplo a seguir usa uma transação para atualizar o preço de vest nas coleções products e sellers :
// Start a session session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); productsCollection = session.getDatabase("test").products; sellersCollection = session.getDatabase("test").sellers; // Start a transaction session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } ); // Operations inside the transaction try { productsCollection.updateOne( { sellerId: 456, name: "vest" }, { $set: { price: 25 } } ); sellersCollection.updateOne( { }, { $set: { "products.$[element].price": 25 } }, { arrayFilters: [ { "element.name": "vest" } ] } ); } catch (error) { // Cancel transaction on error session.abortTransaction(); throw error; } // Commit the transaction using write concern set at transaction start session.commitTransaction(); session.endSession();
Resultados
Para confirmar que o preço foi atualizado e que os dados são consistentes, consulte as coleções products e sellers.
Consultar a coleção de produtos
db.products.find( { sellerId: 456, name: "vest" } )
Saída:
[ { _id: ObjectId("64d506c3ddebf45734d06c58"), sellerId: 456, name: 'vest', price: 25, rating: 4.7 } ]
Consultar a coleção de vendedores
db.sellers.find( { id: 456, "products.name": "vest" } )
Saída:
[ { _id: ObjectId("64d516d9ddebf45734d06c5a"), id: 456, name: 'Cool Clothes Co', location: { address: '21643 Andreane Shores', state: 'Ohio', country: 'United States' }, phone: '567-555-0105', products: [ { name: 'sweater', price: 30 }, { name: 't-shirt', price: 10 }, { name: 'vest', price: 25 } ] } ]
Saiba mais
Para ver outras maneiras de forçar a consistência dos dados, consulte: