【 TiDB 使用环境】生产环境
【 TiDB 版本】v7.1.1
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
想向大家请教一下,默认全局是悲观锁的情况下,如何在用Java 代码实现session 级别的乐观锁。
背景是我有个批量插入的操作,其实写入冲突几乎没有,只是先保证原子性,我应该如何做呢?
【 TiDB 使用环境】生产环境
【 TiDB 版本】v7.1.1
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
想向大家请教一下,默认全局是悲观锁的情况下,如何在用Java 代码实现session 级别的乐观锁。
背景是我有个批量插入的操作,其实写入冲突几乎没有,只是先保证原子性,我应该如何做呢?
https://docs.pingcap.com/zh/tidb/stable/sql-statement-begin#mysql-兼容性
如果是框架包了一层,你需要看看框架的实现。
对于Tidb来说,你begin的时候就可以指定这个事务是乐观的还是悲观的。
或者修改tidb 参数,改成乐观的,默认是悲观,这样代码就可以不动了
pessimistic-auto-commit
tidb_txn_mode='pessimistic'
) 时,自动提交的事务使用的事务模式。默认情况下,即使开启全局悲观事务模式,自动提交事务依然使用乐观事务模式来执行。当开启该配置项后(设置为 true
),在全局悲观事务模式下,自动提交事务将也使用悲观事务模式执行。行为与其他显式提交的悲观事务相同。INSERT INTO SELECT
语句。谢谢您的回答,但是我发现一个现象,想再请教:
我写了一段批量插入的代码,并没有去写类似这种代码:
connection.createStatement().executeUpdate(txnComment + "begin optimistic");
就是单纯一个batch insert , 也没有设置auto commit = false。
连接串是:
characterEncoding=utf8&useSSL=false&useServerPrepStmts=true&prepStmtCacheSqlLimit=10000000000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultfetchsize=-2147483648
但是我发现Grafana 的metrics 里面竟然都是乐观锁的数据
那就是自动提交了,默认自动提交是乐观的,pessimistic-auto-commit=true 时(默认false),自动提交才是悲观呢。
那么再问您下,batch insert auto commit =false 还能算一次事务吗?能保证原子性吗?或者换句话,batch insert 需要显示开启事务吗?
你好,这个不影响呢,开显式还是隐式,这个要看业务代码与数据库呢,一般都是开自动提交,想用显式的话,那就在代码里加begin ,commit 这些就好。相比mysql的话,tidb 多了乐观锁,所以,参数也需要注意下
乐观事务模型就是直接提交,遇到冲突就回滚。比较适合冲突率不高的场景,因为直接提交大概率会成功,冲突是小概率事件,但是一旦遇到事务冲突,回滚的代价会比较大。
悲观事务模型就是在真正提交事务前,先尝试对需要修改的资源上锁,只有在确保事务一定能够执行成功后,才开始提交。好处是对于冲突率高的场景,提前上锁的代价小于事后回滚的代价,而且还能以比较低的代价解决多个并发事务互相冲突导致谁也成功不了的场景。
冲突率不高的场景下,悲观事务没有乐观事务处理高效。
此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。