Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transactton Token error: 'Incorrect syntax near 'begin'.' on server #473

Closed
xingsongs opened this issue Dec 26, 2023 · 5 comments
Closed
Labels
help wanted Extra attention is needed

Comments

@xingsongs
Copy link

database:sql server 2016.

Call to start transaction:
 let mut txn = CONTEXT.rb.acquire_begin().await?;

Execute transaction error:
  Token error: 'Incorrect syntax near 'begin'.' on server WIN-B9A9 executing  on line 1 (code: 102, state: 1, class: 15)  

Sql server does not support 'begin'.

Added the following method:

pub async fn acquire_begin_transaction(&self) -> Result<RBatisTxExecutor, Error> {
        let pool = self.rb.get_pool()?;
        let mut conn = pool.get().await?;

        conn.exec("BEGIN TRAN", vec![]).await?;

        Ok(RBatisTxExecutor {
            tx_id: new_snowflake_id(),
            conn: Mutex::new(Box::new(conn)),
            rb: self.rb.clone(),
            done: false,
        })
    }


Execute  error:
Token error: 'Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.' on server WIN-B9A9 executing  on line 0 (code: 266, state: 2, class: 16)

Please give me some advice?

@zhuxiujia
Copy link
Member

zhuxiujia commented Dec 27, 2023

database:sql server 2016.

Call to start transaction:
 let mut txn = CONTEXT.rb.acquire_begin().await?;

Execute transaction error:
  Token error: 'Incorrect syntax near 'begin'.' on server WIN-B9A9 executing  on line 1 (code: 102, state: 1, class: 15)  

Sql server does not support 'begin'.

Added the following method:

pub async fn acquire_begin_transaction(&self) -> Result<RBatisTxExecutor, Error> {
        let pool = self.rb.get_pool()?;
        let mut conn = pool.get().await?;

        conn.exec("BEGIN TRAN", vec![]).await?;

        Ok(RBatisTxExecutor {
            tx_id: new_snowflake_id(),
            conn: Mutex::new(Box::new(conn)),
            rb: self.rb.clone(),
            done: false,
        })
    }


Execute  error:
Token error: 'Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.' on server WIN-B9A9 executing  on line 0 (code: 266, state: 2, class: 16)

Please give me some advice?

SQL Server 2016 supports starting a transaction using BEGIN TRANSACTION, which is used to explicitly start a transaction in SQL Server. Through BEGIN TRANSACT, you can start a new transaction and then end or roll back the transaction in either COMMIT TRANSACT or Rollback TRANSACT.

I suggest you use an interceptor to modify the transaction statement start to BEGIN TRANSACTION

#[derive(Debug)]
pub struct TxIntercept {}

#[async_trait]
impl Intercept for TxIntercept {
    async fn before(
        &self,
        _task_id: i64,
        _rb: &dyn Executor,
        sql: &mut String,
        _args: &mut Vec<Value>,
        _result: ResultType<&mut Result<ExecResult, Error>, &mut Result<Vec<Value>, Error>>,
    ) -> Result<bool, Error> {
        if sql.contains("begin") {
          *sql = sql.replace("begin","BEGIN TRANSACTION").to_string();
        } else if sql.contains("commit") {
            *sql = sql.replace("commit","COMMIT TRANSACTION").to_string();
        } else if sql.contains("rollback") {
            *sql = sql.replace("rollback","ROLLBACK TRANSACTION").to_string();
        }
        Ok(true)
    }
}
#[tokio::main]
pub async fn main() {
    fast_log::init(fast_log::Config::new().console()).expect("rbatis init fail");
    defer!(|| log::logger().flush());
    let rb = RBatis::new();
    rb.intercepts.push(Arc::new(TxIntercept {}));
}

@zhuxiujia zhuxiujia added the help wanted Extra attention is needed label Dec 27, 2023
@xingsongs
Copy link
Author

database:sql server 2016.

Call to start transaction:
 let mut txn = CONTEXT.rb.acquire_begin().await?;

Execute transaction error:
  Token error: 'Incorrect syntax near 'begin'.' on server WIN-B9A9 executing  on line 1 (code: 102, state: 1, class: 15)  

Sql server does not support 'begin'.

Added the following method:

pub async fn acquire_begin_transaction(&self) -> Result<RBatisTxExecutor, Error> {
        let pool = self.rb.get_pool()?;
        let mut conn = pool.get().await?;

        conn.exec("BEGIN TRAN", vec![]).await?;

        Ok(RBatisTxExecutor {
            tx_id: new_snowflake_id(),
            conn: Mutex::new(Box::new(conn)),
            rb: self.rb.clone(),
            done: false,
        })
    }


Execute  error:
Token error: 'Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.' on server WIN-B9A9 executing  on line 0 (code: 266, state: 2, class: 16)

Please give me some advice?

SQL Server 2016 supports starting a transaction using BEGIN TRANSACTION, which is used to explicitly start a transaction in SQL Server. Through BEGIN TRANSACT, you can start a new transaction and then end or roll back the transaction in either COMMIT TRANSACT or Rollback TRANSACT.

I suggest you use an interceptor to modify the transaction statement start to BEGIN TRANSACTION

#[derive(Debug)]
pub struct TxIntercept {}

#[async_trait]
impl Intercept for TxIntercept {
    async fn before(
        &self,
        _task_id: i64,
        _rb: &dyn Executor,
        sql: &mut String,
        _args: &mut Vec<Value>,
        _result: ResultType<&mut Result<ExecResult, Error>, &mut Result<Vec<Value>, Error>>,
    ) -> Result<bool, Error> {
        if sql.contains("begin") {
          *sql = sql.replace("begin","BEGIN TRANSACTION").to_string();
        } else if sql.contains("commit") {
            *sql = sql.replace("commit","COMMIT TRANSACTION").to_string();
        } else if sql.contains("rollback") {
            *sql = sql.replace("rollback","ROLLBACK TRANSACTION").to_string();
        }
        Ok(true)
    }
}
#[tokio::main]
pub async fn main() {
    fast_log::init(fast_log::Config::new().console()).expect("rbatis init fail");
    defer!(|| log::logger().flush());
    let rb = RBatis::new();
    rb.intercepts.push(Arc::new(TxIntercept {}));
}

Thank you very much that the interceptor has taken effect.
But it still prompts this error:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

@zhuxiujia
Copy link
Member

Thank you very much that the interceptor has taken effect.
But it still prompts this error:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

did you call commit method or rollback ?

@xingsongs
Copy link
Author

Thank you very much that the interceptor has taken effect.
But it still prompts this error:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

did you call commit method or rollback ?

image call CONTEXT.rb.try_acquire_begin().await? report error

@xingsongs
Copy link
Author

#488 Already solved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants