[英]How to create single transaction manager for two oracle different datasources in jdbctemplate
[英]Writes to two different collections in a single transaction
我在我正在使用的應用程序中遇到了一個問題,在單個事務中我試圖更新一個集合中的文檔,並在創建它時在另一個文檔中使用更新的值,因為我添加了批量注冊第二個文件。
這會導致TransientTransactionError
和WriteConflict
日志
到目前為止,這對單個文檔都有效,直到您嘗試再次重復該過程。
這可能嗎?
我嘗試使用不同的傳播級別,例如 REQUIRES_NEW 和 NESTED(不支持),但 oneUpdater.update() 方法沒有運氣,最初它是在沒有 @Transactional 的情況下實現的
@Document
class One {
String id;
int value;
}
@Document
class Two {
String id;
String currentOneValue;
}
class OneUpdater{
int update() {
// searches for single document with the same id and increments value by 1
return mongoTemplate.findAndmodify().getValue();
}
}
class Service {
private final OneUpdater oneUpdater; // uses mongoTemplate.findAndModify to increment value by 1
private final TwoRepository twoRepository; extends MongoRepository
@Transactional
void createTwo {
int value = oneUpdater.update();
Two t = new Two(UUID.randomUuid.toString(), value);
twoRepository.save(t);
}
}
Caused by: com.mongodb.MongoCommandException: Command failed with error 112 (WriteConflict): 'WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction.' on server localhost:27017. The full response is {"errorLabels": ["TransientTransactionError"], "operationTime": {"$timestamp": {"t": 1651680481, "i": 2}}, "ok": 0.0, "errmsg": "WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction.", "code": 112, "codeName": "WriteConflict", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1651680481, "i": 2}}, "signature": {"hash": {"$binary": {"base64": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType": "00"}}, "keyId": 0}}}
那么 Mongo 已經給了你很好的建議或“......或多文檔交易”。
請參閱 Spring 配置 MongoTransactionManager 的示例https://spring.io/blog/2018/06/28/hands-on-mongodb-4-0-transactions-with-spring-data
在此示例中,操作恰好修改了 2 個文檔。
這個問題的解決方案比我想象的要簡單得多,Document One
沒有存儲任何有意義的數據,而是支持Two
提供一些額外的元數據。
我對這個問題的解決方案是用注釋update()
方法
@Transactional(propagation = Propagation.NOT_SUPPORTED
所以我的活動事務將被暫停,並且update()
將以非事務方式執行,因為我不太關心那里的數據並且它停止拋出異常
class OneUpdater{
@Transactional(propagation = Propagation.NOT_SUPPORTED
int update() {
// searches for single document with the same id and increments value by 1
return mongoTemplate.findAndmodify().getValue();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.