cockroachdb / cockroachdb/example-app-rust-postgres

Question - Tokio Postgres (Async)

未关闭
#6 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
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

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。