cockroachdb / cockroachdb/example-app-rust-postgres
Question - Tokio Postgres (Async)
- 主要语言
- Rust
- 星标
- 6
- 派生
- 1
- PR 合并指标
- 30 天内没有已合并 PR
描述
Hello, i have been trying to replicate the example but using Tokio-Postgres. I would like to know if my implementation is correct.
I'm using **deadpool_postgres** too.
```rust
#[derive(Clone)]
pub struct TransactionRepository {
pool: Pool,
}
impl TransactionRepository {
pub fn new(pool: Pool) -> Self {
TransactionRepository { pool }
}
}
#[async_trait]
impl TransactionRepositoryInterface for &TransactionRepository {
async fn make_transaction(&self, data: &WalletTransferEntity) -> Result<(), AppError> {
let mut client: Client = self.pool.get().await.map_err(|e| AppError::DatasourceError(e.to_string()))?;
let mut txn = client.transaction().await?;
let mut i = 0;
match loop {
if i == 3 {
break Ok("Max number of retries".to_string());
}
i = i + 1;
// Set a retry savepoint
// See https://www.cockroachlabs.com/docs/stable/advanced-client-side-transaction-retries
let mut sp = txn.savepoint("cockroach_restart").await?;
match self.transfer(&mut sp, &data).await {
Ok(e) => {
if e.is_empty() {
sp.commit().await?;
break Ok("".to_string());
} else {
break Ok(e);
}
}
Err(ref err)
if err
.code()
.map(|e| *e == SqlState::T_R_SERIALIZATION_FAILURE)
.unwrap_or(false) => {
println!("T_R_SERIALIZATION_FAILURE {:?}", err);
}
r => break r,
}
} {
Ok(t) => {
if t.is_empty() {
txn.commit().await.map_err(|e| AppError::DatasourceError(format!("Error on commit {}", e)))
} else {
Err(AppError::ValidationError(t))
}
}
Err(e) => Err(AppError::DatasourceError(e.to_string()))
}
}
async fn transfer(&self, txn: &mut Transaction, data: &WalletTransferEntity) -> Result {
let from_balance: Decimal = txn.query_one(r#"SELECT balance FROM wallet_accounts WHERE user_id = $1"#, &[&data.from_user_id]).await?.get(0);
if from_balance < data.amount {
return Ok(
"No Enough balance".to_string()
);
}
// Perform the transfer.
txn.execute(
"UPDATE wallet_accounts SET balance = balance - $1 WHERE user_id = $2",
&[&data.amount, &data.from_user_id],
).await?;
txn.execute(
"UPDATE wallet_accounts SET balance = balance + $1 WHERE user_id = $2",
&[&data.amount, &data.to_user_id],
).await?;
Ok("".to_string())
}
}
```
Thanks
贡献指南
这个仓库没有索引到贡献指南
调研方向
该 issue 提供了一个使用 Tokio Postgres 和 deadpool_postgres 实现 TransactionRepository::make_transaction 和 transfer 的 Rust 实现,但没有指明 repository 文件或测试。首先将该代码片段与 repository 中现有的示例以及 Tokio Postgres 的事务文档进行比较。完成的标准是:对该实现的正确性有明确评估,或已记录所需的具体更改。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- postgres, rust
- 领域
- backend, databases
- Issue 类型
- 文档
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 20/100