Reforçar a consistência de dados com transações
Nesta página
Você pode usartransações para impor consistência entre coleções que contêm dados duplicados. As transações atualizam várias coletas 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 impõe consistência de dados em um aplicativo de e-commerce. O esquema de exemplo duplica as informações do produto nas coleções products
e sellers
. Este design de esquema otimiza as queries para produtos e fornecedores.
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 utiliza uma transação no mongosh
. Para ver exemplos de transação para drivers 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: