同时使用async tokio-postgres不是`Send`

我正在尝试使用tokio-postgres条板箱实现异步db访问。这是我尝试过的:

use tokio_postgres::{Client,NoTls,Error};

pub struct Database{
    client: Mutex<Client>
}

impl Database {

    pub async fn some_db_operation(&self,/* args */) -> Result<(),Error> {
        let connection = &mut self.client.lock().expect("Mutex was poisoned");
        let transaction = &mut connection.transaction().await?;
        //executing some queries
        Ok(())
    }

} 

问题是我希望使用warp访问数据库,作为传入的HTTP请求处理的一部分,因此所有内容都应为Send。我收到以下错误:

  --> src/db.rs:27:32
   |
26 |         let connection = &mut self.client.lock().expect("Mutex was poisoned");
   |                               ----------------------------------------------- has type `std::sync::MutexGuard<'_,tokio_postgres::client::Client>` which is not `Send`
27 |         let transaction = &mut connection.transaction().await?;
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here,with `self.client.lock().expect("Mutex was poisoned")` maybe used later

是否有变通方法Send

同步客户端没有这样的问题。

iCMS 回答:同时使用async tokio-postgres不是`Send`

WalletTable(在UserID上调用UserID | email | pass | con_pass | UserRole | Name | CreatedBy | image | CreateDate 的结果)不是Id | UserID | email | Name | amount The relevant part in the docsif (mailtxtbx.Text != "" & pass.Text != "" & conpass.Text != "" & txtname.Text !="") { if (pass.Text == conpass.Text) { if (Filedoc.PostedFile.FileName != "") { if (check1.Checked) { int Uid = -1; byte[] image; Stream s = Filedoc.PostedFile.InputStream; BinaryReader br = new BinaryReader(s); image = br.ReadBytes((Int32)s.Length); // define query to be executed string query = @"INSERT INTO Users (email,pass,con_pass,UserRole,Name,CreatedBy,image,CreateDate) VALUES (@email,@pass,@con_pass,@UserRole,@Name,@CreatedBy,@image,@CreateDate); SELECT SCOPE_IDENTITY();"; // set up SqlCommand in a using block using (SqlCommand objCMD = new SqlCommand(query,con)) { // add parameters using regular ".Add()" method objCMD.Parameters.Add("@email",SqlDbType.VarChar,50).Value = mailtxtbx.Text.Trim(); objCMD.Parameters.Add("@pass",100).Value = pass.Text.Trim(); objCMD.Parameters.Add("@con_pass",50).Value = conpass.Text.Trim(); objCMD.Parameters.Add("@UserRole",50).Value = 'A'; objCMD.Parameters.Add("@Name",50).Value = txtname.Text.Trim(); objCMD.Parameters.Add("@CreatedBy",SqlDbType.Int,50).Value = Uid; objCMD.Parameters.Add("@image",SqlDbType.VarBinary).Value = image; objCMD.Parameters.Add("@CreateDate",SqlDbType.DateTime,100).Value = DateTime.Now; // open connection,execute query,close connection con.Open(); object returnObj = objCMD.ExecuteScalar(); if (returnObj != null) { int.TryParse(returnObj.ToString(),out Uid); } cmd.ExecuteNonQuery(); } con.Close(); if (Uid > 0) { query = @"INSERT INTO UserWallet (Uid,email,amount) VALUES (@Uid,@email,@amount)"; using (SqlCommand objCMD = new SqlCommand(query,con)) { // add parameters using regular ".Add()" method objCMD.Parameters.Add("@Uid",50).Value = Uid; objCMD.Parameters.Add("@email",50).Value = mailtxtbx.Text.Trim(); objCMD.Parameters.Add("@Name",50).Value = txtname.Text.Trim(); objCMD.Parameters.Add("@amount",SqlDbType.Float,100).Value = 0; //Change type here accordingly con.Open(); object returnObj = objCMD.ExecuteScalar(); if (returnObj != null) { int.TryParse(returnObj.ToString(),out Uid); } cmd.ExecuteNonQuery(); lblsuccess.Visible = true; Div1.Visible = true; lblsuccess.Text = "Successfully signed up"; lblsuccess.ForeColor = System.Drawing.Color.Green; lblMessage.Visible = false; dvMessage.Visible = false; mailtxtbx.Text = ""; pass.Text = ""; conpass.Text = ""; txtname.Text = ""; // Response.Redirect("Default.aspx"); } } con.Close(); } } } } 的手动实现(“不是MutexGuard”)。

我强烈建议研究某种连接池,也许使用lock()周围的deadpool_postgres。无论如何,在互斥量后面使用单个客户端可能会降低异步性能。

本文链接:https://www.f2er.com/1840705.html

大家都在问